Annotation of src/usr.bin/kdump/kdump.c, Revision 1.51
1.51 ! otto 1: /* $OpenBSD: kdump.c,v 1.51 2011/06/20 17:51:33 otto Exp $ */
1.4 deraadt 2:
1.1 deraadt 3: /*-
4: * Copyright (c) 1988, 1993
5: * The Regents of the University of California. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
1.21 millert 15: * 3. Neither the name of the University nor the names of its contributors
1.1 deraadt 16: * may be used to endorse or promote products derived from this software
17: * without specific prior written permission.
18: *
19: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29: * SUCH DAMAGE.
30: */
31:
32: #include <sys/param.h>
33: #include <sys/time.h>
34: #include <sys/uio.h>
35: #include <sys/ktrace.h>
36: #include <sys/ioctl.h>
37: #include <sys/ptrace.h>
1.51 ! otto 38: #include <sys/socket.h>
1.28 deraadt 39: #include <sys/sysctl.h>
1.1 deraadt 40: #define _KERNEL
41: #include <sys/errno.h>
42: #undef _KERNEL
43:
1.33 tedu 44: #include <ctype.h>
1.1 deraadt 45: #include <err.h>
46: #include <signal.h>
47: #include <stdio.h>
48: #include <stdlib.h>
49: #include <string.h>
50: #include <unistd.h>
51: #include <vis.h>
52:
53: #include "ktrace.h"
1.22 deraadt 54: #include "kdump.h"
1.51 ! otto 55: #include "kdump_subr.h"
1.12 espie 56: #include "extern.h"
1.1 deraadt 57:
1.31 tedu 58: int timestamp, decimal, iohex, fancy = 1, tail, maxdata;
1.1 deraadt 59: char *tracefile = DEF_TRACEFILE;
60: struct ktr_header ktr_header;
1.17 deraadt 61: pid_t pid = -1;
1.1 deraadt 62:
63: #define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
64:
65: #include <sys/syscall.h>
66:
1.25 mickey 67: #include <compat/linux/linux_syscall.h>
68: #include <compat/svr4/svr4_syscall.h>
1.1 deraadt 69:
70: #define KTRACE
1.19 mickey 71: #define PTRACE
1.7 deraadt 72: #define NFSCLIENT
73: #define NFSSERVER
74: #define SYSVSEM
75: #define SYSVMSG
76: #define SYSVSHM
77: #define LFS
1.25 mickey 78: #include <kern/syscalls.c>
1.1 deraadt 79:
1.25 mickey 80: #include <compat/linux/linux_syscalls.c>
81: #include <compat/svr4/svr4_syscalls.c>
1.1 deraadt 82: #undef KTRACE
1.19 mickey 83: #undef PTRACE
1.7 deraadt 84: #undef NFSCLIENT
85: #undef NFSSERVER
86: #undef SYSVSEM
87: #undef SYSVMSG
88: #undef SYSVSHM
89: #undef LFS
1.1 deraadt 90:
91: struct emulation {
92: char *name; /* Emulation name */
93: char **sysnames; /* Array of system call names */
94: int nsysnames; /* Number of */
95: };
96:
97: static struct emulation emulations[] = {
1.9 deraadt 98: { "native", syscallnames, SYS_MAXSYSCALL },
99: { "linux", linux_syscallnames, LINUX_SYS_MAXSYSCALL },
100: { "svr4", svr4_syscallnames, SVR4_SYS_MAXSYSCALL },
1.49 miod 101: { NULL, NULL, 0 }
1.1 deraadt 102: };
103:
104: struct emulation *current;
105:
106:
107: static char *ptrace_ops[] = {
108: "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U",
109: "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE",
1.15 art 110: "PT_KILL", "PT_ATTACH", "PT_DETACH", "PT_IO",
1.1 deraadt 111: };
112:
1.37 tedu 113: static int fread_tail(void *, size_t, size_t);
1.13 millert 114: static void dumpheader(struct ktr_header *);
115: static void ktrcsw(struct ktr_csw *);
1.37 tedu 116: static void ktremul(char *, size_t);
117: static void ktrgenio(struct ktr_genio *, size_t);
118: static void ktrnamei(const char *, size_t);
1.13 millert 119: static void ktrpsig(struct ktr_psig *);
120: static void ktrsyscall(struct ktr_syscall *);
121: static void ktrsysret(struct ktr_sysret *);
122: static void setemul(const char *);
123: static void usage(void);
1.12 espie 124:
1.1 deraadt 125: int
1.17 deraadt 126: main(int argc, char *argv[])
1.1 deraadt 127: {
1.37 tedu 128: int ch, silent;
129: size_t ktrlen, size;
1.17 deraadt 130: int trpoints = ALL_POINTS;
1.12 espie 131: void *m;
1.1 deraadt 132:
1.3 deraadt 133: current = &emulations[0]; /* native */
1.1 deraadt 134:
1.31 tedu 135: while ((ch = getopt(argc, argv, "e:f:dlm:nRp:Tt:xX")) != -1)
1.1 deraadt 136: switch (ch) {
137: case 'e':
138: setemul(optarg);
139: break;
140: case 'f':
141: tracefile = optarg;
142: break;
143: case 'd':
144: decimal = 1;
145: break;
146: case 'l':
147: tail = 1;
148: break;
149: case 'm':
150: maxdata = atoi(optarg);
151: break;
152: case 'n':
153: fancy = 0;
154: break;
1.17 deraadt 155: case 'p':
156: pid = atoi(optarg);
157: break;
1.1 deraadt 158: case 'R':
159: timestamp = 2; /* relative timestamp */
160: break;
161: case 'T':
162: timestamp = 1;
163: break;
164: case 't':
165: trpoints = getpoints(optarg);
166: if (trpoints < 0)
167: errx(1, "unknown trace point in %s", optarg);
168: break;
1.31 tedu 169: case 'x':
170: iohex = 1;
171: break;
172: case 'X':
173: iohex = 2;
174: break;
1.1 deraadt 175: default:
176: usage();
177: }
1.5 deraadt 178: if (argc > optind)
1.1 deraadt 179: usage();
180:
1.37 tedu 181: m = malloc(size = 1025);
1.1 deraadt 182: if (m == NULL)
1.37 tedu 183: err(1, NULL);
1.1 deraadt 184: if (!freopen(tracefile, "r", stdin))
185: err(1, "%s", tracefile);
186: while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
1.17 deraadt 187: silent = 0;
188: if (pid != -1 && pid != ktr_header.ktr_pid)
189: silent = 1;
190: if (silent == 0 && trpoints & (1<<ktr_header.ktr_type))
1.1 deraadt 191: dumpheader(&ktr_header);
1.37 tedu 192: ktrlen = ktr_header.ktr_len;
1.1 deraadt 193: if (ktrlen > size) {
1.23 tedu 194: void *newm;
195:
196: newm = realloc(m, ktrlen+1);
197: if (newm == NULL)
1.37 tedu 198: err(1, NULL);
1.23 tedu 199: m = newm;
1.1 deraadt 200: size = ktrlen;
201: }
202: if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
203: errx(1, "data too short");
1.17 deraadt 204: if (silent)
205: continue;
1.1 deraadt 206: if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
207: continue;
208: switch (ktr_header.ktr_type) {
209: case KTR_SYSCALL:
210: ktrsyscall((struct ktr_syscall *)m);
211: break;
212: case KTR_SYSRET:
213: ktrsysret((struct ktr_sysret *)m);
214: break;
215: case KTR_NAMEI:
216: ktrnamei(m, ktrlen);
217: break;
218: case KTR_GENIO:
219: ktrgenio((struct ktr_genio *)m, ktrlen);
220: break;
221: case KTR_PSIG:
222: ktrpsig((struct ktr_psig *)m);
223: break;
224: case KTR_CSW:
225: ktrcsw((struct ktr_csw *)m);
226: break;
227: case KTR_EMUL:
228: ktremul(m, ktrlen);
229: break;
230: }
231: if (tail)
232: (void)fflush(stdout);
233: }
1.12 espie 234: exit(0);
1.1 deraadt 235: }
236:
1.12 espie 237: static int
1.37 tedu 238: fread_tail(void *buf, size_t size, size_t num)
1.1 deraadt 239: {
240: int i;
241:
242: while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
243: (void)sleep(1);
244: clearerr(stdin);
245: }
246: return (i);
247: }
248:
1.12 espie 249: static void
1.17 deraadt 250: dumpheader(struct ktr_header *kth)
1.1 deraadt 251: {
1.17 deraadt 252: static struct timeval prevtime;
1.1 deraadt 253: char unknown[64], *type;
254: struct timeval temp;
255:
256: switch (kth->ktr_type) {
257: case KTR_SYSCALL:
258: type = "CALL";
259: break;
260: case KTR_SYSRET:
261: type = "RET ";
262: break;
263: case KTR_NAMEI:
264: type = "NAMI";
265: break;
266: case KTR_GENIO:
267: type = "GIO ";
268: break;
269: case KTR_PSIG:
270: type = "PSIG";
271: break;
272: case KTR_CSW:
273: type = "CSW";
274: break;
275: case KTR_EMUL:
276: type = "EMUL";
277: break;
278: default:
1.17 deraadt 279: (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)",
280: kth->ktr_type);
1.1 deraadt 281: type = unknown;
282: }
283:
1.16 mpech 284: (void)printf("%6ld %-8.*s ", (long)kth->ktr_pid, MAXCOMLEN,
285: kth->ktr_comm);
1.1 deraadt 286: if (timestamp) {
287: if (timestamp == 2) {
288: timersub(&kth->ktr_time, &prevtime, &temp);
289: prevtime = kth->ktr_time;
290: } else
291: temp = kth->ktr_time;
292: (void)printf("%ld.%06ld ", temp.tv_sec, temp.tv_usec);
293: }
294: (void)printf("%s ", type);
295: }
296:
1.12 espie 297: static void
1.17 deraadt 298: ioctldecode(u_long cmd)
1.2 deraadt 299: {
300: char dirbuf[4], *dir = dirbuf;
301:
1.6 deraadt 302: if (cmd & IOC_IN)
303: *dir++ = 'W';
1.2 deraadt 304: if (cmd & IOC_OUT)
305: *dir++ = 'R';
306: *dir = '\0';
307:
1.33 tedu 308: printf(decimal ? ",_IO%s('%c',%lu" : ",_IO%s('%c',%#lx",
309: dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1.2 deraadt 310: if ((cmd & IOC_VOID) == 0)
1.34 tedu 311: printf(decimal ? ",%lu)" : ",%#lx)", (cmd >> 16) & 0xff);
1.2 deraadt 312: else
313: printf(")");
314: }
1.1 deraadt 315:
1.51 ! otto 316: #define print_number(i, n, c) do { \
! 317: if (c) \
! 318: (void)putchar(c); \
! 319: if (decimal) \
! 320: (void)printf("%ld", (long)*i); \
! 321: else \
! 322: (void)printf("%#lx", (long)*i); \
! 323: i++; \
! 324: n--; \
! 325: c = ','; \
! 326: } while (0);
! 327:
1.12 espie 328: static void
1.17 deraadt 329: ktrsyscall(struct ktr_syscall *ktr)
1.1 deraadt 330: {
1.51 ! otto 331: int narg = ktr->ktr_argsize / sizeof(register_t);
1.12 espie 332: register_t *ap;
1.1 deraadt 333:
334: if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0)
335: (void)printf("[%d]", ktr->ktr_code);
336: else
337: (void)printf("%s", current->sysnames[ktr->ktr_code]);
338: ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
1.27 mickey 339: (void)putchar('(');
1.51 ! otto 340: if (narg) {
1.27 mickey 341: char c = '\0';
1.1 deraadt 342: if (fancy) {
1.51 ! otto 343: switch (ktr->ktr_code) {
! 344: case SYS_ioctl: {
1.12 espie 345: const char *cp;
1.17 deraadt 346:
1.1 deraadt 347: if (decimal)
1.27 mickey 348: (void)printf("%ld", (long)*ap);
1.1 deraadt 349: else
1.27 mickey 350: (void)printf("%#lx", (long)*ap);
1.1 deraadt 351: ap++;
1.51 ! otto 352: narg--;
1.1 deraadt 353: if ((cp = ioctlname(*ap)) != NULL)
354: (void)printf(",%s", cp);
1.2 deraadt 355: else
356: ioctldecode(*ap);
1.1 deraadt 357: c = ',';
358: ap++;
1.51 ! otto 359: narg--;
! 360: break;
! 361: }
! 362: case SYS___sysctl: {
1.27 mickey 363: int *np, n;
364:
365: n = ap[1];
1.28 deraadt 366: if (n > CTL_MAXNAME)
367: n = CTL_MAXNAME;
1.27 mickey 368: np = (int *)(ap + 6);
369: for (; n--; np++) {
370: if (c)
371: putchar(c);
372: printf("%d", *np);
373: c = '.';
374: }
375:
376: c = ',';
377: ap += 2;
1.51 ! otto 378: narg -= 2;
! 379: break;
! 380: }
! 381: case SYS_ptrace:
1.24 miod 382: if (*ap >= 0 && *ap <
1.1 deraadt 383: sizeof(ptrace_ops) / sizeof(ptrace_ops[0]))
1.27 mickey 384: (void)printf("%s", ptrace_ops[*ap]);
1.24 miod 385: else switch(*ap) {
386: #ifdef PT_GETFPREGS
387: case PT_GETFPREGS:
1.27 mickey 388: (void)printf("PT_GETFPREGS");
1.24 miod 389: break;
390: #endif
391: case PT_GETREGS:
1.27 mickey 392: (void)printf("PT_GETREGS");
1.24 miod 393: break;
394: #ifdef PT_SETFPREGS
395: case PT_SETFPREGS:
1.27 mickey 396: (void)printf("PT_SETFPREGS");
1.24 miod 397: break;
398: #endif
399: case PT_SETREGS:
1.27 mickey 400: (void)printf("PT_SETREGS");
1.24 miod 401: break;
402: #ifdef PT_STEP
403: case PT_STEP:
1.27 mickey 404: (void)printf("PT_STEP");
1.24 miod 405: break;
406: #endif
407: #ifdef PT_WCOOKIE
408: case PT_WCOOKIE:
1.27 mickey 409: (void)printf("PT_WCOOKIE");
1.24 miod 410: break;
411: #endif
412: default:
1.27 mickey 413: (void)printf("%ld", (long)*ap);
1.24 miod 414: break;
415: }
1.1 deraadt 416: c = ',';
417: ap++;
1.51 ! otto 418: narg--;
! 419: break;
! 420: case SYS_access:
! 421: print_number(ap, narg, c);
! 422: (void)putchar(',');
! 423: accessmodename((int)*ap);
! 424: ap++;
! 425: narg--;
! 426: break;
! 427: case SYS_chmod:
! 428: case SYS_fchmod:
! 429: print_number(ap, narg, c);
! 430: (void)putchar(',');
! 431: modename((int)*ap);
! 432: ap++;
! 433: narg--;
! 434: break;
! 435: case SYS_fcntl: {
! 436: int cmd;
! 437: int arg;
! 438: print_number(ap, narg, c);
! 439: cmd = *ap;
! 440: arg = *++ap;
! 441: (void)putchar(',');
! 442: fcntlcmdname(cmd, arg, decimal);
! 443: ap++;
! 444: narg -= 2;
! 445: break;
! 446: }
! 447: case SYS_flock:
! 448: print_number(ap, narg, c);
! 449: (void)putchar(',');
! 450: flockname((int)*ap);
! 451: ap++;
! 452: narg--;
! 453: break;
! 454: case SYS_getrlimit:
! 455: case SYS_setrlimit:
! 456: rlimitname((int)*ap);
! 457: ap++;
! 458: narg--;
! 459: c = ',';
! 460: break;
! 461: case SYS_getsockopt:
! 462: case SYS_setsockopt:
! 463: print_number(ap, narg, c);
! 464: (void)putchar(',');
! 465: sockoptlevelname((int)*ap, decimal);
! 466: if ((int)*ap == SOL_SOCKET) {
! 467: ap++;
! 468: narg--;
! 469: (void)putchar(',');
! 470: sockoptname((int)*ap);
! 471: }
! 472: ap++;
! 473: narg--;
! 474: break;
! 475: case SYS_kill:
! 476: print_number(ap, narg, c);
! 477: (void)putchar(',');
! 478: signame((int)*ap);
! 479: ap++;
! 480: narg--;
! 481: break;
! 482: case SYS_lseek:
! 483: print_number(ap, narg, c);
! 484: /* skip padding */
! 485: ap++;
! 486: narg--;
! 487: print_number(ap, narg, c);
! 488: (void)putchar(',');
! 489: whencename((int)*ap);
! 490: ap++;
! 491: narg--;
! 492: break;
! 493: case SYS_madvise:
! 494: print_number(ap, narg, c);
! 495: print_number(ap, narg, c);
! 496: (void)putchar(',');
! 497: madvisebehavname((int)*ap);
! 498: ap++;
! 499: narg--;
! 500: break;
! 501: case SYS_minherit:
! 502: print_number(ap, narg, c);
! 503: print_number(ap, narg, c);
! 504: (void)putchar(',');
! 505: minheritname((int)*ap);
! 506: ap++;
! 507: narg--;
! 508: break;
! 509: case SYS_mlockall:
! 510: mlockallname((int)*ap);
! 511: ap++;
! 512: narg--;
! 513: break;
! 514: case SYS_mmap:
! 515: print_number(ap, narg, c);
! 516: print_number(ap, narg, c);
! 517: (void)putchar(',');
! 518: mmapprotname((int)*ap);
! 519: (void)putchar(',');
! 520: ap++;
! 521: narg--;
! 522: mmapflagsname((int)*ap);
! 523: ap++;
! 524: narg--;
! 525: print_number(ap, narg, c);
! 526: /* skip padding */
! 527: ap++;
! 528: narg--;
! 529: break;
! 530: case SYS_mprotect:
! 531: print_number(ap, narg, c);
! 532: print_number(ap, narg, c);
! 533: (void)putchar(',');
! 534: mmapprotname((int)*ap);
! 535: ap++;
! 536: narg--;
! 537: break;
! 538: case SYS_mquery:
! 539: print_number(ap, narg, c);
! 540: print_number(ap, narg, c);
! 541: (void)putchar(',');
! 542: mmapprotname((int)*ap);
! 543: ap++;
! 544: narg--;
! 545: (void)putchar(',');
! 546: mmapflagsname((int)*ap);
! 547: ap++;
! 548: narg--;
! 549: print_number(ap, narg, c);
! 550: /* skip padding */
! 551: ap++;
! 552: narg--;
! 553: break;
! 554: case SYS_msync:
! 555: print_number(ap, narg, c);
! 556: print_number(ap, narg, c);
! 557: (void)putchar(',');
! 558: msyncflagsname((int)*ap);
! 559: ap++;
! 560: narg--;
! 561: break;
! 562: case SYS_msgctl:
! 563: print_number(ap, narg, c);
! 564: (void)putchar(',');
! 565: shmctlname((int)*ap);
! 566: ap++;
! 567: narg--;
! 568: break;
! 569: case SYS_open: {
! 570: int flags;
! 571: int mode;
! 572: print_number(ap, narg, c);
! 573: flags = *ap;
! 574: mode = *++ap;
! 575: (void)putchar(',');
! 576: flagsandmodename(flags, mode, decimal);
! 577: ap++;
! 578: narg -= 2;
! 579: break;
! 580: }
! 581: case SYS_pread:
! 582: case SYS_preadv:
! 583: case SYS_pwrite:
! 584: case SYS_pwritev:
! 585: print_number(ap, narg, c);
! 586: print_number(ap, narg, c);
! 587: print_number(ap, narg, c);
! 588: /* skip padding */
! 589: ap++;
! 590: narg--;
! 591: break;
! 592: case SYS_recvmsg:
! 593: case SYS_sendmsg:
! 594: print_number(ap, narg, c);
! 595: print_number(ap, narg, c);
! 596: (void)putchar(',');
! 597: sendrecvflagsname((int)*ap);
! 598: ap++;
! 599: narg--;
! 600: break;
! 601: case SYS_recvfrom:
! 602: case SYS_sendto:
! 603: print_number(ap, narg, c);
! 604: print_number(ap, narg, c);
! 605: print_number(ap, narg, c);
! 606: (void)putchar(',');
! 607: sendrecvflagsname((int)*ap);
! 608: ap++;
! 609: narg--;
! 610: break;
! 611: case SYS___semctl:
! 612: print_number(ap, narg, c);
! 613: print_number(ap, narg, c);
! 614: (void)putchar(',');
! 615: semctlname((int)*ap);
! 616: ap++;
! 617: narg--;
! 618: break;
! 619: case SYS_semget:
! 620: print_number(ap, narg, c);
! 621: print_number(ap, narg, c);
! 622: (void)putchar(',');
! 623: semgetname((int)*ap);
! 624: ap++;
! 625: narg--;
! 626: break;
! 627: case SYS_shmat:
! 628: print_number(ap, narg, c);
! 629: print_number(ap, narg, c);
! 630: (void)putchar(',');
! 631: shmatname((int)*ap);
! 632: ap++;
! 633: narg--;
! 634: break;
! 635: case SYS_shmctl:
! 636: print_number(ap, narg, c);
! 637: (void)putchar(',');
! 638: shmctlname((int)*ap);
! 639: ap++;
! 640: narg--;
! 641: break;
! 642: case SYS_sigaction:
! 643: signame((int)*ap);
! 644: ap++;
! 645: narg--;
! 646: c = ',';
! 647: break;
! 648: case SYS_sigprocmask:
! 649: sigprocmaskhowname((int)*ap);
! 650: ap++;
! 651: narg--;
! 652: c = ',';
! 653: break;
! 654: case SYS_socket: {
! 655: int sockdomain = (int)*ap;
! 656: sockdomainname(sockdomain);
! 657: ap++;
! 658: narg--;
! 659: (void)putchar(',');
! 660: socktypename((int)*ap);
! 661: ap++;
! 662: narg--;
! 663: if (sockdomain == PF_INET ||
! 664: sockdomain == PF_INET6) {
! 665: (void)putchar(',');
! 666: sockipprotoname((int)*ap);
! 667: ap++;
! 668: narg--;
! 669: }
! 670: c = ',';
! 671: break;
! 672: }
! 673: case SYS_socketpair:
! 674: sockdomainname((int)*ap);
! 675: ap++;
! 676: narg--;
! 677: (void)putchar(',');
! 678: socktypename((int)*ap);
! 679: ap++;
! 680: narg--;
! 681: c = ',';
! 682: break;
! 683: case SYS_truncate:
! 684: case SYS_ftruncate:
! 685: print_number(ap, narg, c);
! 686: /* skip padding */
! 687: ap++;
! 688: narg--;
! 689: break;
! 690: case SYS_wait4:
! 691: print_number(ap, narg, c);
! 692: print_number(ap, narg, c);
! 693: (void)putchar(',');
! 694: wait4optname((int)*ap);
! 695: ap++;
! 696: narg--;
! 697: break;
1.1 deraadt 698: }
699: }
1.51 ! otto 700: while (narg) {
1.27 mickey 701: if (c)
702: putchar(c);
1.1 deraadt 703: if (decimal)
1.27 mickey 704: (void)printf("%ld", (long)*ap);
1.1 deraadt 705: else
1.27 mickey 706: (void)printf("%#lx", (long)*ap);
1.1 deraadt 707: c = ',';
708: ap++;
1.51 ! otto 709: narg--;
1.1 deraadt 710: }
711: }
1.27 mickey 712: (void)printf(")\n");
1.1 deraadt 713: }
714:
1.12 espie 715: static void
1.17 deraadt 716: ktrsysret(struct ktr_sysret *ktr)
1.1 deraadt 717: {
1.50 deraadt 718: register_t ret = ktr->ktr_retval;
1.12 espie 719: int error = ktr->ktr_error;
720: int code = ktr->ktr_code;
1.1 deraadt 721:
722: if (code >= current->nsysnames || code < 0)
723: (void)printf("[%d] ", code);
724: else
725: (void)printf("%s ", current->sysnames[code]);
726:
727: if (error == 0) {
728: if (fancy) {
1.50 deraadt 729: (void)printf("%ld", (long)ret);
1.1 deraadt 730: if (ret < 0 || ret > 9)
1.50 deraadt 731: (void)printf("/%#lx", (long)ret);
1.1 deraadt 732: } else {
733: if (decimal)
1.50 deraadt 734: (void)printf("%ld", (long)ret);
1.1 deraadt 735: else
1.50 deraadt 736: (void)printf("%#lx", (long)ret);
1.1 deraadt 737: }
738: } else if (error == ERESTART)
739: (void)printf("RESTART");
740: else if (error == EJUSTRETURN)
741: (void)printf("JUSTRETURN");
742: else {
743: (void)printf("-1 errno %d", ktr->ktr_error);
744: if (fancy)
745: (void)printf(" %s", strerror(ktr->ktr_error));
746: }
747: (void)putchar('\n');
748: }
749:
1.12 espie 750: static void
1.37 tedu 751: ktrnamei(const char *cp, size_t len)
1.1 deraadt 752: {
1.37 tedu 753: (void)printf("\"%.*s\"\n", (int)len, cp);
1.1 deraadt 754: }
755:
1.12 espie 756: static void
1.37 tedu 757: ktremul(char *cp, size_t len)
1.1 deraadt 758: {
759: char name[1024];
760:
761: if (len >= sizeof(name))
762: errx(1, "Emulation name too long");
763:
764: strncpy(name, cp, len);
765: name[len] = '\0';
766: (void)printf("\"%s\"\n", name);
767:
768: setemul(name);
769: }
770:
1.12 espie 771: static void
1.37 tedu 772: ktrgenio(struct ktr_genio *ktr, size_t len)
1.1 deraadt 773: {
1.37 tedu 774: unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
775: int i, j;
776: size_t datalen = len - sizeof(struct ktr_genio);
1.12 espie 777: static int screenwidth = 0;
1.31 tedu 778: int col = 0, width, bpl;
1.32 tedu 779: unsigned char visbuf[5], *cp, c;
1.1 deraadt 780:
781: if (screenwidth == 0) {
782: struct winsize ws;
783:
784: if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
785: ws.ws_col > 8)
786: screenwidth = ws.ws_col;
787: else
788: screenwidth = 80;
789: }
1.37 tedu 790: printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1.1 deraadt 791: ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
792: if (maxdata && datalen > maxdata)
793: datalen = maxdata;
1.31 tedu 794: if (iohex && !datalen)
795: return;
796: if (iohex == 1) {
797: putchar('\t');
798: col = 8;
799: for (i = 0; i < datalen; i++) {
1.35 tedu 800: printf("%02x", dp[i]);
1.31 tedu 801: col += 3;
802: if (i < datalen - 1) {
803: if (col + 3 > screenwidth) {
804: printf("\n\t");
805: col = 8;
806: } else
807: putchar(' ');
808: }
809: }
810: putchar('\n');
811: return;
812: }
813: if (iohex == 2) {
814: bpl = (screenwidth - 13)/4;
815: if (bpl <= 0)
816: bpl = 1;
817: for (i = 0; i < datalen; i += bpl) {
818: printf(" %04x: ", i);
819: for (j = 0; j < bpl; j++) {
820: if (i+j >= datalen)
821: printf(" ");
822: else
1.35 tedu 823: printf("%02x ", dp[i+j]);
1.31 tedu 824: }
825: putchar(' ');
826: for (j = 0; j < bpl; j++) {
827: if (i+j >= datalen)
828: break;
829: c = dp[i+j];
830: if (!isprint(c))
831: c = '.';
832: putchar(c);
833: }
834: putchar('\n');
835: }
836: return;
837: }
1.1 deraadt 838: (void)printf(" \"");
839: col = 8;
840: for (; datalen > 0; datalen--, dp++) {
1.31 tedu 841: (void)vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
1.1 deraadt 842: cp = visbuf;
1.17 deraadt 843:
1.1 deraadt 844: /*
845: * Keep track of printables and
846: * space chars (like fold(1)).
847: */
848: if (col == 0) {
849: (void)putchar('\t');
850: col = 8;
851: }
1.17 deraadt 852: switch (*cp) {
1.1 deraadt 853: case '\n':
854: col = 0;
855: (void)putchar('\n');
856: continue;
857: case '\t':
858: width = 8 - (col&07);
859: break;
860: default:
861: width = strlen(cp);
862: }
863: if (col + width > (screenwidth-2)) {
864: (void)printf("\\\n\t");
865: col = 8;
866: }
867: col += width;
868: do {
869: (void)putchar(*cp++);
870: } while (*cp);
871: }
872: if (col == 0)
873: (void)printf(" ");
874: (void)printf("\"\n");
875: }
876:
1.12 espie 877: static void
1.17 deraadt 878: ktrpsig(struct ktr_psig *psig)
1.1 deraadt 879: {
880: (void)printf("SIG%s ", sys_signame[psig->signo]);
881: if (psig->action == SIG_DFL)
1.14 deraadt 882: (void)printf("SIG_DFL code %d", psig->code);
1.1 deraadt 883: else
1.14 deraadt 884: (void)printf("caught handler=0x%lx mask=0x%x",
885: (u_long)psig->action, psig->mask);
886: switch (psig->signo) {
887: case SIGSEGV:
888: case SIGILL:
889: case SIGBUS:
890: case SIGFPE:
891: printf(" addr=%p trapno=%d", psig->si.si_addr,
892: psig->si.si_trapno);
893: break;
894: default:
895: break;
896: }
897: printf("\n");
1.1 deraadt 898: }
899:
1.12 espie 900: static void
1.17 deraadt 901: ktrcsw(struct ktr_csw *cs)
1.1 deraadt 902: {
903: (void)printf("%s %s\n", cs->out ? "stop" : "resume",
904: cs->user ? "user" : "kernel");
905: }
906:
1.12 espie 907: static void
1.17 deraadt 908: usage(void)
1.1 deraadt 909: {
910:
1.19 mickey 911: extern char *__progname;
912: fprintf(stderr, "usage: %s "
1.40 sobrado 913: "[-dlnRTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n"
914: "%*s[-t [ceinsw]]\n",
1.51 ! otto 915: __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
1.1 deraadt 916: exit(1);
917: }
918:
1.12 espie 919: static void
1.17 deraadt 920: setemul(const char *name)
1.1 deraadt 921: {
922: int i;
1.17 deraadt 923:
1.1 deraadt 924: for (i = 0; emulations[i].name != NULL; i++)
925: if (strcmp(emulations[i].name, name) == 0) {
926: current = &emulations[i];
927: return;
928: }
929: warnx("Emulation `%s' unknown", name);
930: }