nrelease - fix/improve livecd
[dragonfly.git] / usr.bin / kdump / kdump.c
CommitLineData
984263bc
MD
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.
dc71b7ab 13 * 3. Neither the name of the University nor the names of its contributors
984263bc
MD
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.
1de703da
MD
28 *
29 * @(#) Copyright (c) 1988, 1993 The Regents of the University of California. All rights reserved.
30 * @(#)kdump.c 8.1 (Berkeley) 6/6/93
988bb7fd 31 * $FreeBSD: src/usr.bin/kdump/kdump.c,v 1.29 2006/05/20 14:27:22 netchild Exp $
984263bc
MD
32 */
33
cc970022
MD
34#define _KERNEL_STRUCTURES
35
984263bc 36#include <sys/errno.h>
984263bc 37#include <sys/param.h>
984263bc 38#include <sys/time.h>
984263bc
MD
39#include <sys/ktrace.h>
40#include <sys/ioctl.h>
41#include <sys/ptrace.h>
fcf53d9b 42#include <dlfcn.h>
984263bc
MD
43#include <err.h>
44#include <locale.h>
45#include <stdio.h>
46#include <stdlib.h>
47#include <string.h>
48#include <unistd.h>
49#include <vis.h>
50#include "ktrace.h"
988bb7fd 51#include "kdump_subr.h"
984263bc 52
3c2616ee
SW
53extern const char *ioctlname(u_long);
54
55static int dumpheader(struct ktr_header *);
56static int fread_tail(void *, int, int);
57static void ktrcsw(struct ktr_csw *);
58static void ktrgenio(struct ktr_genio *, int);
59static void ktrnamei(char *, int);
60static void ktrpsig(struct ktr_psig *);
61static void ktrsyscall(struct ktr_syscall *);
62static void ktrsysret(struct ktr_sysret *);
63static void ktruser(int, unsigned char *);
64static void ktruser_malloc(int, unsigned char *);
fcf53d9b 65static void ktruser_rtld(int, unsigned char *);
3c2616ee
SW
66static void timevalfix(struct timeval *);
67static void timevalsub(struct timeval *, struct timeval *);
68static void usage(void);
69
0d4982d0 70int timestamp, decimal, fancy = 1, tail, maxdata = 64;
2af36526 71int fixedformat;
91a87936 72int cpustamp;
3c2616ee 73const char *tracefile = DEF_TRACEFILE;
984263bc
MD
74struct ktr_header ktr_header;
75
76#define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
77
3c2616ee 78int
1d1731fa 79main(int argc, char **argv)
984263bc 80{
cc1033d4
JS
81 int ch, col, ktrlen, size;
82 pid_t do_pid = -1;
815943a9 83 void *m;
984263bc 84 int trpoints = ALL_POINTS;
cc1033d4 85 char *cp;
984263bc 86
d119d94d 87 setlocale(LC_CTYPE, "");
984263bc 88
91a87936 89 while ((ch = getopt(argc,argv,"acf:djlm:np:RTt:")) != -1)
984263bc
MD
90 switch((char)ch) {
91 case 'f':
92 tracefile = optarg;
93 break;
2af36526
MD
94 case 'j':
95 fixedformat = 1;
96 break;
91a87936
MD
97 case 'c':
98 cpustamp = 1;
99 break;
100 case 'a':
101 timestamp = 2; /* relative timestamp */
102 cpustamp = 1;
103 break;
984263bc
MD
104 case 'd':
105 decimal = 1;
106 break;
107 case 'l':
108 tail = 1;
109 break;
110 case 'm':
111 maxdata = atoi(optarg);
112 break;
113 case 'n':
114 fancy = 0;
115 break;
cc1033d4
JS
116 case 'p':
117 do_pid = strtoul(optarg, &cp, 0);
118 if (*cp != 0)
119 errx(1,"invalid number %s", optarg);
120 break;
984263bc
MD
121 case 'R':
122 timestamp = 2; /* relative timestamp */
123 break;
124 case 'T':
125 timestamp = 1;
126 break;
127 case 't':
128 trpoints = getpoints(optarg);
129 if (trpoints < 0)
130 errx(1, "unknown trace point in %s", optarg);
131 break;
132 default:
133 usage();
134 }
135
136 if (argc > optind)
137 usage();
138
139 m = (void *)malloc(size = 1025);
140 if (m == NULL)
141 errx(1, "%s", strerror(ENOMEM));
142 if (!freopen(tracefile, "r", stdin))
143 err(1, "%s", tracefile);
144 while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
cc1033d4
JS
145 if (trpoints & (1 << ktr_header.ktr_type) &&
146 (do_pid == -1 || ktr_header.ktr_pid == do_pid))
147 col = dumpheader(&ktr_header);
148 else
149 col = -1;
984263bc
MD
150 if ((ktrlen = ktr_header.ktr_len) < 0)
151 errx(1, "bogus length 0x%x", ktrlen);
152 if (ktrlen > size) {
153 m = (void *)realloc(m, ktrlen+1);
154 if (m == NULL)
155 errx(1, "%s", strerror(ENOMEM));
156 size = ktrlen;
157 }
158 if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
159 errx(1, "data too short");
160 if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
161 continue;
cc1033d4
JS
162 if (col == -1)
163 continue;
984263bc
MD
164 switch (ktr_header.ktr_type) {
165 case KTR_SYSCALL:
166 ktrsyscall((struct ktr_syscall *)m);
167 break;
168 case KTR_SYSRET:
169 ktrsysret((struct ktr_sysret *)m);
170 break;
171 case KTR_NAMEI:
55f88487 172 case KTR_SYSCTL:
984263bc
MD
173 ktrnamei(m, ktrlen);
174 break;
175 case KTR_GENIO:
176 ktrgenio((struct ktr_genio *)m, ktrlen);
177 break;
178 case KTR_PSIG:
179 ktrpsig((struct ktr_psig *)m);
180 break;
181 case KTR_CSW:
182 ktrcsw((struct ktr_csw *)m);
183 break;
184 case KTR_USER:
185 ktruser(ktrlen, m);
186 break;
187 }
188 if (tail)
d119d94d 189 fflush(stdout);
984263bc 190 }
3c2616ee 191 exit(0);
984263bc
MD
192}
193
3c2616ee
SW
194static int
195fread_tail(void *buf, int size, int num)
984263bc
MD
196{
197 int i;
198
199 while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
d119d94d 200 sleep(1);
984263bc
MD
201 clearerr(stdin);
202 }
203 return (i);
204}
205
3c2616ee 206static int
1d1731fa 207dumpheader(struct ktr_header *kth)
984263bc
MD
208{
209 static char unknown[64];
210 static struct timeval prevtime, temp;
3c2616ee 211 const char *type;
cc1033d4 212 int col;
984263bc
MD
213
214 switch (kth->ktr_type) {
215 case KTR_SYSCALL:
216 type = "CALL";
217 break;
218 case KTR_SYSRET:
219 type = "RET ";
220 break;
221 case KTR_NAMEI:
222 type = "NAMI";
223 break;
224 case KTR_GENIO:
225 type = "GIO ";
226 break;
227 case KTR_PSIG:
228 type = "PSIG";
229 break;
230 case KTR_CSW:
231 type = "CSW";
232 break;
233 case KTR_USER:
234 type = "USER";
235 break;
55f88487
SW
236 case KTR_SYSCTL:
237 type = "SCTL";
238 break;
984263bc 239 default:
d119d94d 240 sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type);
984263bc
MD
241 type = unknown;
242 }
243
2af36526
MD
244 if (kth->ktr_tid || (kth->ktr_flags & KTRH_THREADED) || fixedformat)
245 col = printf("%5d:%-4d", kth->ktr_pid, kth->ktr_tid);
246 else
247 col = printf("%5d", kth->ktr_pid);
91a87936 248 if (cpustamp)
af5fd90d 249 col += printf(" %2d", KTRH_CPUID_DECODE(kth->ktr_flags));
2af36526 250 col += printf(" %-8.*s ", MAXCOMLEN, kth->ktr_comm);
984263bc
MD
251 if (timestamp) {
252 if (timestamp == 2) {
253 temp = kth->ktr_time;
254 timevalsub(&kth->ktr_time, &prevtime);
255 prevtime = temp;
256 }
cc1033d4 257 col += printf("%ld.%06ld ",
984263bc
MD
258 kth->ktr_time.tv_sec, kth->ktr_time.tv_usec);
259 }
cc1033d4
JS
260 col += printf("%s ", type);
261 return col;
984263bc
MD
262}
263
264#include <sys/syscall.h>
265#define KTRACE
ab800d2a 266#include <kern/syscalls.c>
984263bc
MD
267#undef KTRACE
268int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]);
269
3c2616ee 270static const char *ptrace_ops[] = {
984263bc
MD
271 "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U",
272 "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE",
273 "PT_KILL", "PT_STEP", "PT_ATTACH", "PT_DETACH",
274};
275
3c2616ee 276static void
815943a9 277ktrsyscall(struct ktr_syscall *ktr)
984263bc 278{
815943a9
SW
279 int narg = ktr->ktr_narg;
280 register_t *ip;
984263bc
MD
281
282 if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)
d119d94d 283 printf("[%d]", ktr->ktr_code);
984263bc 284 else
d119d94d 285 printf("%s", syscallnames[ktr->ktr_code]);
984263bc
MD
286 ip = &ktr->ktr_args[0];
287 if (narg) {
288 char c = '(';
289 if (fancy) {
988bb7fd
MS
290
291#define print_number(i,n,c) do { \
292 if (decimal) \
d119d94d 293 printf("%c%ld", c, (long)*i); \
988bb7fd 294 else \
d119d94d 295 printf("%c%#lx", c, (long)*i); \
988bb7fd
MS
296 i++; \
297 n--; \
298 c = ','; \
299 } while (0);
300
984263bc 301 if (ktr->ktr_code == SYS_ioctl) {
3c2616ee 302 const char *cp;
988bb7fd 303 print_number(ip,narg,c);
984263bc 304 if ((cp = ioctlname(*ip)) != NULL)
d119d94d 305 printf(",%s", cp);
984263bc
MD
306 else {
307 if (decimal)
d119d94d 308 printf(",%ld", (long)*ip);
984263bc 309 else
d119d94d 310 printf(",%#lx ", (long)*ip);
984263bc
MD
311 }
312 c = ',';
313 ip++;
314 narg--;
37ffcab2
SW
315 } else if (ktr->ktr_code == SYS_access ||
316 ktr->ktr_code == SYS_eaccess ||
317 ktr->ktr_code == SYS_faccessat) {
318 if (ktr->ktr_code == SYS_faccessat)
319 print_number(ip,narg,c);
988bb7fd 320 print_number(ip,narg,c);
d119d94d 321 putchar(',');
988bb7fd
MS
322 accessmodename ((int)*ip);
323 ip++;
324 narg--;
37ffcab2
SW
325 if (ktr->ktr_code == SYS_faccessat) {
326 putchar(',');
327 atflagsname((int)*ip);
328 ip++;
329 narg--;
330 }
7eac1315
SK
331 } else if (ktr->ktr_code == SYS_open ||
332 ktr->ktr_code == SYS_mq_open) {
988bb7fd
MS
333 int flags;
334 int mode;
335 print_number(ip,narg,c);
336 flags = *ip;
337 mode = *++ip;
d119d94d 338 putchar(',');
988bb7fd
MS
339 flagsandmodename (flags, mode, decimal);
340 ip++;
341 narg-=2;
342 } else if (ktr->ktr_code == SYS_wait4) {
343 print_number(ip,narg,c);
344 print_number(ip,narg,c);
d119d94d 345 putchar(',');
988bb7fd
MS
346 wait4optname ((int)*ip);
347 ip++;
348 narg--;
349 } else if (ktr->ktr_code == SYS_chmod ||
350 ktr->ktr_code == SYS_fchmod ||
37ffcab2 351 ktr->ktr_code == SYS_fchmodat ||
988bb7fd 352 ktr->ktr_code == SYS_lchmod) {
37ffcab2
SW
353 if (ktr->ktr_code == SYS_fchmodat)
354 print_number(ip,narg,c);
988bb7fd 355 print_number(ip,narg,c);
d119d94d 356 putchar(',');
988bb7fd
MS
357 modename ((int)*ip);
358 ip++;
359 narg--;
37ffcab2
SW
360 if (ktr->ktr_code == SYS_fchmodat) {
361 putchar(',');
362 atflagsname((int)*ip);
363 ip++;
364 narg--;
365 }
366 } else if (ktr->ktr_code == SYS_fchownat ||
367 ktr->ktr_code == SYS_fstatat ||
368 ktr->ktr_code == SYS_linkat ||
369 ktr->ktr_code == SYS_unlinkat ||
370 ktr->ktr_code == SYS_utimensat) {
371 print_number(ip,narg,c);
372 print_number(ip,narg,c);
373 if (ktr->ktr_code != SYS_unlinkat)
374 print_number(ip,narg,c);
375 if (ktr->ktr_code == SYS_fchownat ||
376 ktr->ktr_code == SYS_linkat)
377 print_number(ip,narg,c);
378 putchar(',');
379 atflagsname((int)*ip);
380 ip++;
381 narg--;
988bb7fd
MS
382 } else if (ktr->ktr_code == SYS_mknod) {
383 print_number(ip,narg,c);
d119d94d 384 putchar(',');
988bb7fd
MS
385 modename ((int)*ip);
386 ip++;
387 narg--;
37ffcab2
SW
388 } else if (ktr->ktr_code == SYS_getfsstat ||
389 ktr->ktr_code == SYS_getvfsstat) {
988bb7fd 390 print_number(ip,narg,c);
37ffcab2
SW
391 if (ktr->ktr_code == SYS_getvfsstat)
392 print_number(ip,narg,c);
988bb7fd 393 print_number(ip,narg,c);
d119d94d 394 putchar(',');
988bb7fd
MS
395 getfsstatflagsname ((int)*ip);
396 ip++;
397 narg--;
398 } else if (ktr->ktr_code == SYS_mount) {
399 print_number(ip,narg,c);
400 print_number(ip,narg,c);
d119d94d 401 putchar(',');
988bb7fd
MS
402 mountflagsname ((int)*ip);
403 ip++;
404 narg--;
405 } else if (ktr->ktr_code == SYS_unmount) {
406 print_number(ip,narg,c);
d119d94d 407 putchar(',');
988bb7fd
MS
408 mountflagsname ((int)*ip);
409 ip++;
410 narg--;
411 } else if (ktr->ktr_code == SYS_recvmsg ||
412 ktr->ktr_code == SYS_sendmsg) {
413 print_number(ip,narg,c);
414 print_number(ip,narg,c);
d119d94d 415 putchar(',');
988bb7fd
MS
416 sendrecvflagsname ((int)*ip);
417 ip++;
418 narg--;
419 } else if (ktr->ktr_code == SYS_recvfrom ||
420 ktr->ktr_code == SYS_sendto) {
421 print_number(ip,narg,c);
422 print_number(ip,narg,c);
423 print_number(ip,narg,c);
d119d94d 424 putchar(',');
988bb7fd
MS
425 sendrecvflagsname ((int)*ip);
426 ip++;
427 narg--;
428 } else if (ktr->ktr_code == SYS_chflags ||
37ffcab2
SW
429 ktr->ktr_code == SYS_chflagsat ||
430 ktr->ktr_code == SYS_fchflags ||
431 ktr->ktr_code == SYS_lchflags) {
432 if (ktr->ktr_code == SYS_chflagsat)
433 print_number(ip,narg,c);
988bb7fd 434 print_number(ip,narg,c);
d119d94d 435 putchar(',');
513a5bc4 436 chflagsname((long)*ip);
988bb7fd
MS
437 ip++;
438 narg--;
37ffcab2
SW
439 if (ktr->ktr_code == SYS_chflagsat) {
440 putchar(',');
441 atflagsname((int)*ip);
442 ip++;
443 narg--;
444 }
988bb7fd
MS
445 } else if (ktr->ktr_code == SYS_kill) {
446 print_number(ip,narg,c);
d119d94d 447 putchar(',');
988bb7fd
MS
448 signame((int)*ip);
449 ip++;
450 narg--;
451 } else if (ktr->ktr_code == SYS_reboot) {
d119d94d 452 putchar('(');
988bb7fd
MS
453 rebootoptname((int)*ip);
454 ip++;
455 narg--;
456 } else if (ktr->ktr_code == SYS_umask) {
d119d94d 457 putchar('(');
988bb7fd
MS
458 modename((int)*ip);
459 ip++;
460 narg--;
461 } else if (ktr->ktr_code == SYS_msync) {
462 print_number(ip,narg,c);
463 print_number(ip,narg,c);
d119d94d 464 putchar(',');
988bb7fd
MS
465 msyncflagsname((int)*ip);
466 ip++;
467 narg--;
468 } else if (ktr->ktr_code == SYS_mmap) {
469 print_number(ip,narg,c);
470 print_number(ip,narg,c);
d119d94d 471 putchar(',');
988bb7fd 472 mmapprotname ((int)*ip);
d119d94d 473 putchar(',');
988bb7fd
MS
474 ip++;
475 narg--;
476 mmapflagsname ((int)*ip);
477 ip++;
478 narg--;
479 } else if (ktr->ktr_code == SYS_mprotect) {
480 print_number(ip,narg,c);
481 print_number(ip,narg,c);
d119d94d 482 putchar(',');
988bb7fd
MS
483 mmapprotname ((int)*ip);
484 ip++;
485 narg--;
486 } else if (ktr->ktr_code == SYS_madvise) {
487 print_number(ip,narg,c);
488 print_number(ip,narg,c);
d119d94d 489 putchar(',');
988bb7fd
MS
490 madvisebehavname((int)*ip);
491 ip++;
492 narg--;
493 } else if (ktr->ktr_code == SYS_setpriority) {
d119d94d 494 putchar('(');
988bb7fd
MS
495 prioname((int)*ip);
496 ip++;
497 narg--;
ae59b38c
SK
498 c = ',';
499 print_number(ip,narg,c);
500 print_number(ip,narg,c);
988bb7fd
MS
501 } else if (ktr->ktr_code == SYS_fcntl) {
502 int cmd;
503 int arg;
504 print_number(ip,narg,c);
505 cmd = *ip;
506 arg = *++ip;
d119d94d 507 putchar(',');
988bb7fd
MS
508 fcntlcmdname(cmd, arg, decimal);
509 ip++;
510 narg-=2;
511 } else if (ktr->ktr_code == SYS_socket) {
d119d94d 512 putchar('(');
988bb7fd
MS
513 sockdomainname((int)*ip);
514 ip++;
515 narg--;
d119d94d 516 putchar(',');
988bb7fd
MS
517 socktypename((int)*ip);
518 ip++;
519 narg--;
520 c = ',';
521 } else if (ktr->ktr_code == SYS_setsockopt ||
522 ktr->ktr_code == SYS_getsockopt) {
523 print_number(ip,narg,c);
d119d94d 524 putchar(',');
988bb7fd
MS
525 sockoptlevelname((int)*ip, decimal);
526 ip++;
527 narg--;
d119d94d 528 putchar(',');
988bb7fd
MS
529 sockoptname((int)*ip);
530 ip++;
531 narg--;
532 } else if (ktr->ktr_code == SYS_lseek) {
533 print_number(ip,narg,c);
534 /* Hidden 'pad' argument, not in lseek(2) */
535 print_number(ip,narg,c);
536 print_number(ip,narg,c);
d119d94d 537 putchar(',');
988bb7fd
MS
538 whencename ((int)*ip);
539 ip++;
540 narg--;
541 } else if (ktr->ktr_code == SYS_flock) {
542 print_number(ip,narg,c);
d119d94d 543 putchar(',');
988bb7fd
MS
544 flockname((int)*ip);
545 ip++;
546 narg--;
547 } else if (ktr->ktr_code == SYS_mkfifo ||
548 ktr->ktr_code == SYS_mkdir) {
549 print_number(ip,narg,c);
d119d94d 550 putchar(',');
988bb7fd
MS
551 modename((int)*ip);
552 ip++;
553 narg--;
554 } else if (ktr->ktr_code == SYS_shutdown) {
555 print_number(ip,narg,c);
d119d94d 556 putchar(',');
988bb7fd
MS
557 shutdownhowname((int)*ip);
558 ip++;
559 narg--;
560 } else if (ktr->ktr_code == SYS_socketpair) {
d119d94d 561 putchar('(');
988bb7fd
MS
562 sockdomainname((int)*ip);
563 ip++;
564 narg--;
d119d94d 565 putchar(',');
988bb7fd
MS
566 socktypename((int)*ip);
567 ip++;
568 narg--;
569 c = ',';
570 } else if (ktr->ktr_code == SYS_getrlimit ||
571 ktr->ktr_code == SYS_setrlimit) {
d119d94d 572 putchar('(');
988bb7fd
MS
573 rlimitname((int)*ip);
574 ip++;
575 narg--;
576 c = ',';
577 } else if (ktr->ktr_code == SYS_quotactl) {
578 print_number(ip,narg,c);
579 quotactlname((int)*ip);
580 ip++;
581 narg--;
582 c = ',';
583 } else if (ktr->ktr_code == SYS_rtprio) {
d119d94d 584 putchar('(');
988bb7fd
MS
585 rtprioname((int)*ip);
586 ip++;
587 narg--;
588 c = ',';
589 } else if (ktr->ktr_code == SYS___semctl) {
590 print_number(ip,narg,c);
591 print_number(ip,narg,c);
592 semctlname((int)*ip);
593 ip++;
594 narg--;
595 } else if (ktr->ktr_code == SYS_semget) {
596 print_number(ip,narg,c);
597 print_number(ip,narg,c);
598 semgetname((int)*ip);
599 ip++;
600 narg--;
601 } else if (ktr->ktr_code == SYS_msgctl) {
602 print_number(ip,narg,c);
603 shmctlname((int)*ip);
604 ip++;
605 narg--;
606 } else if (ktr->ktr_code == SYS_shmat) {
607 print_number(ip,narg,c);
608 print_number(ip,narg,c);
609 shmatname((int)*ip);
610 ip++;
611 narg--;
612 } else if (ktr->ktr_code == SYS_shmctl) {
613 print_number(ip,narg,c);
614 shmctlname((int)*ip);
615 ip++;
616 narg--;
617 } else if (ktr->ktr_code == SYS_minherit) {
618 print_number(ip,narg,c);
619 print_number(ip,narg,c);
620 minheritname((int)*ip);
621 ip++;
622 narg--;
623 } else if (ktr->ktr_code == SYS_rfork) {
d119d94d 624 putchar('(');
988bb7fd
MS
625 rforkname((int)*ip);
626 ip++;
627 narg--;
628 c = ',';
629 } else if (ktr->ktr_code == SYS_lio_listio) {
d119d94d 630 putchar('(');
988bb7fd
MS
631 lio_listioname((int)*ip);
632 ip++;
633 narg--;
634 c = ',';
635 } else if (ktr->ktr_code == SYS_mlockall) {
d119d94d 636 putchar('(');
988bb7fd
MS
637 mlockallname((int)*ip);
638 ip++;
639 narg--;
640 } else if (ktr->ktr_code == SYS_sched_setscheduler) {
641 print_number(ip,narg,c);
642 schedpolicyname((int)*ip);
643 ip++;
644 narg--;
645 } else if (ktr->ktr_code == SYS_sched_get_priority_max ||
646 ktr->ktr_code == SYS_sched_get_priority_min) {
d119d94d 647 putchar('(');
988bb7fd
MS
648 schedpolicyname((int)*ip);
649 ip++;
650 narg--;
651 } else if (ktr->ktr_code == SYS_sendfile) {
652 print_number(ip,narg,c);
653 print_number(ip,narg,c);
654 print_number(ip,narg,c);
655 print_number(ip,narg,c);
656 print_number(ip,narg,c);
657 print_number(ip,narg,c);
658 sendfileflagsname((int)*ip);
659 ip++;
660 narg--;
661 } else if (ktr->ktr_code == SYS_kldsym) {
662 print_number(ip,narg,c);
663 kldsymcmdname((int)*ip);
664 ip++;
665 narg--;
666 } else if (ktr->ktr_code == SYS_sigprocmask) {
d119d94d 667 putchar('(');
988bb7fd
MS
668 sigprocmaskhowname((int)*ip);
669 ip++;
670 narg--;
671 c = ',';
672 } else if (ktr->ktr_code == SYS___acl_get_file ||
673 ktr->ktr_code == SYS___acl_set_file ||
674 ktr->ktr_code == SYS___acl_get_fd ||
675 ktr->ktr_code == SYS___acl_set_fd ||
676 ktr->ktr_code == SYS___acl_delete_file ||
677 ktr->ktr_code == SYS___acl_delete_fd ||
678 ktr->ktr_code == SYS___acl_aclcheck_file ||
679 ktr->ktr_code == SYS___acl_aclcheck_fd) {
680 print_number(ip,narg,c);
681 acltypename((int)*ip);
682 ip++;
683 narg--;
684 } else if (ktr->ktr_code == SYS_sigaction) {
d119d94d 685 putchar('(');
988bb7fd
MS
686 signame((int)*ip);
687 ip++;
688 narg--;
689 c = ',';
690 } else if (ktr->ktr_code == SYS_extattrctl) {
691 print_number(ip,narg,c);
692 extattrctlname((int)*ip);
693 ip++;
694 narg--;
984263bc 695 } else if (ktr->ktr_code == SYS_ptrace) {
e62ef63c 696 if (*ip < (register_t)NELEM(ptrace_ops) && *ip >= 0)
d119d94d 697 printf("(%s", ptrace_ops[*ip]);
984263bc
MD
698#ifdef PT_GETREGS
699 else if (*ip == PT_GETREGS)
d119d94d 700 printf("(%s", "PT_GETREGS");
984263bc
MD
701#endif
702#ifdef PT_SETREGS
703 else if (*ip == PT_SETREGS)
d119d94d 704 printf("(%s", "PT_SETREGS");
984263bc
MD
705#endif
706#ifdef PT_GETFPREGS
707 else if (*ip == PT_GETFPREGS)
d119d94d 708 printf("(%s", "PT_GETFPREGS");
984263bc
MD
709#endif
710#ifdef PT_SETFPREGS
711 else if (*ip == PT_SETFPREGS)
d119d94d 712 printf("(%s", "PT_SETFPREGS");
984263bc
MD
713#endif
714#ifdef PT_GETDBREGS
715 else if (*ip == PT_GETDBREGS)
d119d94d 716 printf("(%s", "PT_GETDBREGS");
984263bc
MD
717#endif
718#ifdef PT_SETDBREGS
719 else if (*ip == PT_SETDBREGS)
d119d94d 720 printf("(%s", "PT_SETDBREGS");
984263bc
MD
721#endif
722 else
d119d94d 723 printf("(%ld", (long)*ip);
984263bc
MD
724 c = ',';
725 ip++;
726 narg--;
493ee394
SW
727 } else if (ktr->ktr_code == SYS_clock_getres ||
728 ktr->ktr_code == SYS_clock_gettime ||
729 ktr->ktr_code == SYS_clock_settime) {
730 putchar('(');
731 clockidname((int)*ip);
732 ip++;
733 narg--;
734 c = ',';
e5ef1af1
SW
735 } else if (ktr->ktr_code == SYS_fpathconf ||
736 ktr->ktr_code == SYS_lpathconf ||
737 ktr->ktr_code == SYS_pathconf) {
738 print_number(ip,narg,c);
739 putchar(',');
740 pathconfname((int)*ip);
741 ip++;
742 narg--;
37ffcab2
SW
743 } else if (ktr->ktr_code == SYS_kenv) {
744 putchar('(');
745 kenvactname((int)*ip);
746 ip++;
747 narg--;
748 c = ',';
749 } else if (ktr->ktr_code == SYS_usched_set) {
750 print_number(ip,narg,c);
751 putchar(',');
752 uschedcmdname((int)*ip);
753 ip++;
754 narg--;
755 } else if (ktr->ktr_code == SYS_sys_checkpoint) {
756 putchar('(');
757 ckpttypename((int)*ip);
758 ip++;
759 narg--;
760 c = ',';
761 } else if (ktr->ktr_code == SYS_procctl) {
762 print_number(ip,narg,c);
763 print_number(ip,narg,c);
764 putchar(',');
765 procctlcmdname((int)*ip);
766 ip++;
767 narg--;
768 c = ',';
769 } else if (ktr->ktr_code == SYS_mountctl) {
770 print_number(ip,narg,c);
771 putchar(',');
772 mountctlopname((int)*ip);
773 ip++;
774 narg--;
775 c = ',';
776 } else if (ktr->ktr_code == SYS_varsym_list ||
777 ktr->ktr_code == SYS_varsym_set) {
778 putchar('(');
779 varsymlvlname((int)*ip);
780 ip++;
781 narg--;
782 c = ',';
984263bc
MD
783 }
784 }
48cbc382 785 while (narg > 0) {
988bb7fd 786 print_number(ip,narg,c);
984263bc 787 }
d119d94d 788 putchar(')');
984263bc 789 }
d119d94d 790 putchar('\n');
984263bc
MD
791}
792
3c2616ee 793static void
1d1731fa 794ktrsysret(struct ktr_sysret *ktr)
984263bc 795{
815943a9
SW
796 register_t ret = ktr->ktr_retval;
797 int error = ktr->ktr_error;
798 int code = ktr->ktr_code;
984263bc
MD
799
800 if (code >= nsyscalls || code < 0)
d119d94d 801 printf("[%d] ", code);
984263bc 802 else
d119d94d 803 printf("%s ", syscallnames[code]);
984263bc
MD
804
805 if (error == 0) {
806 if (fancy) {
d119d94d 807 printf("%ld", (long)ret);
984263bc 808 if (ret < 0 || ret > 9)
d119d94d 809 printf("/%#lx", (long)ret);
984263bc
MD
810 } else {
811 if (decimal)
d119d94d 812 printf("%ld", (long)ret);
984263bc 813 else
d119d94d 814 printf("%#lx", (long)ret);
984263bc
MD
815 }
816 } else if (error == ERESTART)
d119d94d 817 printf("RESTART");
984263bc 818 else if (error == EJUSTRETURN)
d119d94d 819 printf("JUSTRETURN");
984263bc 820 else {
d119d94d 821 printf("-1 errno %d", ktr->ktr_error);
984263bc 822 if (fancy)
d119d94d 823 printf(" %s", strerror(ktr->ktr_error));
984263bc 824 }
d119d94d 825 putchar('\n');
984263bc
MD
826}
827
3c2616ee 828static void
1d1731fa 829ktrnamei(char *cp, int len)
984263bc 830{
d119d94d 831 printf("\"%.*s\"\n", len, cp);
984263bc
MD
832}
833
3c2616ee 834static void
1d1731fa 835ktrgenio(struct ktr_genio *ktr, int len)
984263bc 836{
815943a9
SW
837 int datalen = len - sizeof (struct ktr_genio);
838 char *dp = (char *)ktr + sizeof (struct ktr_genio);
839 char *cp;
840 int col = 0;
841 int width;
984263bc 842 char visbuf[5];
3c2616ee 843 static int screenwidth = 0;
984263bc
MD
844
845 if (screenwidth == 0) {
846 struct winsize ws;
847
848 if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
849 ws.ws_col > 8)
850 screenwidth = ws.ws_col;
851 else
852 screenwidth = 80;
853 }
854 printf("fd %d %s %d byte%s\n", ktr->ktr_fd,
855 ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen,
856 datalen == 1 ? "" : "s");
857 if (maxdata && datalen > maxdata)
858 datalen = maxdata;
d119d94d 859 printf(" \"");
984263bc
MD
860 col = 8;
861 for (;datalen > 0; datalen--, dp++) {
d119d94d 862 vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
984263bc
MD
863 cp = visbuf;
864 /*
865 * Keep track of printables and
866 * space chars (like fold(1)).
867 */
868 if (col == 0) {
d119d94d 869 putchar('\t');
984263bc
MD
870 col = 8;
871 }
872 switch(*cp) {
873 case '\n':
874 col = 0;
d119d94d 875 putchar('\n');
984263bc
MD
876 continue;
877 case '\t':
878 width = 8 - (col&07);
879 break;
880 default:
881 width = strlen(cp);
882 }
883 if (col + width > (screenwidth-2)) {
d119d94d 884 printf("\\\n\t");
984263bc
MD
885 col = 8;
886 }
887 col += width;
888 do {
d119d94d 889 putchar(*cp++);
984263bc
MD
890 } while (*cp);
891 }
892 if (col == 0)
d119d94d
SW
893 printf(" ");
894 printf("\"\n");
984263bc
MD
895}
896
3c2616ee 897const char *signames[NSIG] = {
984263bc
MD
898 "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */
899 "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */
900 "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */
901 "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */
902 "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */
903 "USR2", NULL, /* 31 - 32 */
904};
905
3c2616ee 906static void
1d1731fa 907ktrpsig(struct ktr_psig *psig)
984263bc 908{
d119d94d 909 printf("SIG%s ", signames[psig->signo]);
984263bc 910 if (psig->action == SIG_DFL)
d119d94d 911 printf("SIG_DFL\n");
984263bc 912 else
d119d94d 913 printf("caught handler=0x%lx mask=0x%x code=0x%x\n",
3c2616ee 914 (u_long)psig->action, psig->mask.__bits[0], psig->code);
984263bc
MD
915}
916
3c2616ee 917static void
1d1731fa 918ktrcsw(struct ktr_csw *cs)
984263bc 919{
d119d94d 920 printf("%s %s\n", cs->out ? "stop" : "resume",
984263bc
MD
921 cs->user ? "user" : "kernel");
922}
923
fcf53d9b
JM
924#define UTRACE_DLOPEN_START 1
925#define UTRACE_DLOPEN_STOP 2
926#define UTRACE_DLCLOSE_START 3
927#define UTRACE_DLCLOSE_STOP 4
928#define UTRACE_LOAD_OBJECT 5
929#define UTRACE_UNLOAD_OBJECT 6
930#define UTRACE_ADD_RUNDEP 7
931#define UTRACE_PRELOAD_FINISHED 8
932#define UTRACE_INIT_CALL 9
933#define UTRACE_FINI_CALL 10
934
935struct utrace_rtld {
936 char sig[4]; /* 'RTLD' */
937 int event;
938 void *handle;
939 void *mapbase;
940 size_t mapsize;
941 int refcnt;
942 char name[MAXPATHLEN];
943};
944
945static void
946ktruser_rtld(int len, unsigned char *p)
947{
948 struct utrace_rtld *ut = (struct utrace_rtld *)p;
949 void *parent;
950 int mode;
951
952 switch (ut->event) {
953 case UTRACE_DLOPEN_START:
954 mode = ut->refcnt;
955 printf("dlopen(%s, ", ut->name);
956 switch (mode & RTLD_MODEMASK) {
957 case RTLD_NOW:
958 printf("RTLD_NOW");
959 break;
960 case RTLD_LAZY:
961 printf("RTLD_LAZY");
962 break;
963 default:
964 printf("%#x", mode & RTLD_MODEMASK);
965 }
966 if (mode & RTLD_GLOBAL)
967 printf(" | RTLD_GLOBAL");
968 if (mode & RTLD_TRACE)
969 printf(" | RTLD_TRACE");
970 if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE))
971 printf(" | %#x", mode &
972 ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE));
973 printf(")\n");
974 break;
975 case UTRACE_DLOPEN_STOP:
976 printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name,
977 ut->refcnt);
978 break;
979 case UTRACE_DLCLOSE_START:
980 printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name,
981 ut->refcnt);
982 break;
983 case UTRACE_DLCLOSE_STOP:
984 printf("dlclose(%p) finished\n", ut->handle);
985 break;
986 case UTRACE_LOAD_OBJECT:
987 printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle,
988 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
989 ut->name);
990 break;
991 case UTRACE_UNLOAD_OBJECT:
992 printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle,
993 ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1,
994 ut->name);
995 break;
996 case UTRACE_ADD_RUNDEP:
997 parent = ut->mapbase;
998 printf("RTLD: %p now depends on %p (%s, %d)\n", parent,
999 ut->handle, ut->name, ut->refcnt);
1000 break;
1001 case UTRACE_PRELOAD_FINISHED:
1002 printf("RTLD: LD_PRELOAD finished\n");
1003 break;
1004 case UTRACE_INIT_CALL:
1005 printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle,
1006 ut->name);
1007 break;
1008 case UTRACE_FINI_CALL:
1009 printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle,
1010 ut->name);
1011 break;
1012 default:
1013 p += 4;
1014 len -= 4;
1015 printf("RTLD: %d ", len);
1016 while (len--)
1017 if (decimal)
1018 printf(" %d", *p++);
1019 else
1020 printf(" %02x", *p++);
1021 printf("\n");
1022 }
1023}
1024
433ec267
HT
1025struct utrace_malloc {
1026 void *p;
1027 size_t s;
1028 void *r;
1029};
1030
3c2616ee
SW
1031static void
1032ktruser_malloc(int len __unused, unsigned char *p)
433ec267
HT
1033{
1034 struct utrace_malloc *ut = (struct utrace_malloc *)p;
1035
1036 if (ut->p == NULL) {
1037 if (ut->s == 0 && ut->r == NULL)
1038 printf("malloc_init()\n");
1039 else
1040 printf("%p = malloc(%zu)\n", ut->r, ut->s);
1041 } else {
1042 if (ut->s == 0)
1043 printf("free(%p)\n", ut->p);
1044 else
1045 printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s);
1046 }
1047}
1048
3c2616ee 1049static void
1d1731fa 1050ktruser(int len, unsigned char *p)
984263bc 1051{
fcf53d9b
JM
1052
1053 if (len >= 8 && bcmp(p, "RTLD", 4) == 0) {
1054 ktruser_rtld(len, p);
1055 return;
1056 }
1057
433ec267
HT
1058 if (len == sizeof(struct utrace_malloc)) {
1059 ktruser_malloc(len, p);
1060 return;
1061 }
1062
d119d94d 1063 printf("%d ", len);
984263bc 1064 while (len--)
d119d94d
SW
1065 printf(" %02x", *p++);
1066 printf("\n");
984263bc
MD
1067}
1068
3c2616ee 1069static void
1d1731fa 1070usage(void)
984263bc 1071{
d119d94d 1072 fprintf(stderr,
cc1033d4 1073 "usage: kdump [-dnlRT] [-f trfile] [-m maxdata] [-t [cnisuw]] [-p pid]\n");
984263bc
MD
1074 exit(1);
1075}
0044293f 1076
3c2616ee 1077static void
0044293f
SW
1078timevalsub(struct timeval *t1, struct timeval *t2)
1079{
1080 t1->tv_sec -= t2->tv_sec;
1081 t1->tv_usec -= t2->tv_usec;
1082 timevalfix(t1);
1083}
1084
3c2616ee 1085static void
0044293f
SW
1086timevalfix(struct timeval *t1)
1087{
1088 if (t1->tv_usec < 0) {
1089 t1->tv_sec--;
1090 t1->tv_usec += 1000000;
1091 }
1092 if (t1->tv_usec >= 1000000) {
1093 t1->tv_sec++;
1094 t1->tv_usec -= 1000000;
1095 }
1096}