Annotation of src/usr.bin/kdump/kdump.c, Revision 1.62
1.62 ! otto 1: /* $OpenBSD: kdump.c,v 1.61 2011/07/19 18:20:11 matthew 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>
1.62 ! otto 37: #include <sys/malloc.h>
! 38: #include <sys/namei.h>
1.1 deraadt 39: #include <sys/ptrace.h>
1.62 ! otto 40: #include <sys/sem.h>
! 41: #include <sys/shm.h>
1.51 otto 42: #include <sys/socket.h>
1.28 deraadt 43: #include <sys/sysctl.h>
1.55 otto 44: #include <sys/socket.h>
45: #include <sys/un.h>
1.62 ! otto 46: #include <sys/vmmeter.h>
1.55 otto 47: #include <sys/stat.h>
1.62 ! otto 48: #include <sys/tty.h>
1.55 otto 49: #include <netinet/in.h>
50: #include <arpa/inet.h>
1.1 deraadt 51: #define _KERNEL
52: #include <sys/errno.h>
53: #undef _KERNEL
1.62 ! otto 54: #include <ddb/db_var.h>
! 55: #include <machine/cpu.h>
1.1 deraadt 56:
1.33 tedu 57: #include <ctype.h>
1.1 deraadt 58: #include <err.h>
1.61 matthew 59: #include <fcntl.h>
1.1 deraadt 60: #include <signal.h>
61: #include <stdio.h>
62: #include <stdlib.h>
1.55 otto 63: #include <stdint.h>
1.1 deraadt 64: #include <string.h>
1.55 otto 65: #include <grp.h>
66: #include <pwd.h>
1.1 deraadt 67: #include <unistd.h>
68: #include <vis.h>
69:
70: #include "ktrace.h"
1.22 deraadt 71: #include "kdump.h"
1.51 otto 72: #include "kdump_subr.h"
1.12 espie 73: #include "extern.h"
1.1 deraadt 74:
1.58 otto 75: int timestamp, decimal, iohex, fancy = 1, tail, maxdata = INT_MAX, resolv;
1.1 deraadt 76: char *tracefile = DEF_TRACEFILE;
77: struct ktr_header ktr_header;
1.17 deraadt 78: pid_t pid = -1;
1.1 deraadt 79:
1.55 otto 80: #define TIME_FORMAT "%b %e %T %Y"
1.1 deraadt 81: #define eqs(s1, s2) (strcmp((s1), (s2)) == 0)
82:
83: #include <sys/syscall.h>
84:
1.25 mickey 85: #include <compat/linux/linux_syscall.h>
1.1 deraadt 86:
87: #define KTRACE
1.19 mickey 88: #define PTRACE
1.7 deraadt 89: #define NFSCLIENT
90: #define NFSSERVER
91: #define SYSVSEM
92: #define SYSVMSG
93: #define SYSVSHM
94: #define LFS
1.25 mickey 95: #include <kern/syscalls.c>
1.1 deraadt 96:
1.25 mickey 97: #include <compat/linux/linux_syscalls.c>
1.1 deraadt 98: #undef KTRACE
1.19 mickey 99: #undef PTRACE
1.7 deraadt 100: #undef NFSCLIENT
101: #undef NFSSERVER
102: #undef SYSVSEM
103: #undef SYSVMSG
104: #undef SYSVSHM
105: #undef LFS
1.1 deraadt 106:
107: struct emulation {
108: char *name; /* Emulation name */
109: char **sysnames; /* Array of system call names */
110: int nsysnames; /* Number of */
111: };
112:
113: static struct emulation emulations[] = {
1.9 deraadt 114: { "native", syscallnames, SYS_MAXSYSCALL },
115: { "linux", linux_syscallnames, LINUX_SYS_MAXSYSCALL },
1.49 miod 116: { NULL, NULL, 0 }
1.1 deraadt 117: };
118:
1.59 otto 119: static struct emulation *current;
1.60 otto 120: static struct emulation *def_emul;
1.59 otto 121:
122: struct pid_emul {
123: struct emulation *e;
124: pid_t p;
125: };
126:
127: static struct pid_emul *pe_table;
128: static size_t pe_size;
1.1 deraadt 129:
130:
131: static char *ptrace_ops[] = {
132: "PT_TRACE_ME", "PT_READ_I", "PT_READ_D", "PT_READ_U",
133: "PT_WRITE_I", "PT_WRITE_D", "PT_WRITE_U", "PT_CONTINUE",
1.15 art 134: "PT_KILL", "PT_ATTACH", "PT_DETACH", "PT_IO",
1.1 deraadt 135: };
136:
1.52 otto 137: static int narg;
138: static register_t *ap;
139: static char sep;
140:
1.59 otto 141: static void mappidtoemul(pid_t, struct emulation *);
142: static struct emulation * findemul(pid_t);
1.37 tedu 143: static int fread_tail(void *, size_t, size_t);
1.13 millert 144: static void dumpheader(struct ktr_header *);
145: static void ktrcsw(struct ktr_csw *);
1.37 tedu 146: static void ktremul(char *, size_t);
147: static void ktrgenio(struct ktr_genio *, size_t);
148: static void ktrnamei(const char *, size_t);
1.13 millert 149: static void ktrpsig(struct ktr_psig *);
150: static void ktrsyscall(struct ktr_syscall *);
1.62 ! otto 151: static const char *kresolvsysctl(int, int *, int);
1.13 millert 152: static void ktrsysret(struct ktr_sysret *);
1.55 otto 153: static void ktrstruct(char *, size_t);
1.13 millert 154: static void setemul(const char *);
155: static void usage(void);
1.61 matthew 156: static void atfd(int);
1.12 espie 157:
1.1 deraadt 158: int
1.17 deraadt 159: main(int argc, char *argv[])
1.1 deraadt 160: {
1.37 tedu 161: int ch, silent;
162: size_t ktrlen, size;
1.17 deraadt 163: int trpoints = ALL_POINTS;
1.12 espie 164: void *m;
1.1 deraadt 165:
1.60 otto 166: def_emul = current = &emulations[0]; /* native */
1.1 deraadt 167:
1.55 otto 168: while ((ch = getopt(argc, argv, "e:f:dlm:nrRp:Tt:xX")) != -1)
1.1 deraadt 169: switch (ch) {
170: case 'e':
171: setemul(optarg);
1.60 otto 172: def_emul = current;
1.1 deraadt 173: break;
174: case 'f':
175: tracefile = optarg;
176: break;
177: case 'd':
178: decimal = 1;
179: break;
180: case 'l':
181: tail = 1;
182: break;
183: case 'm':
184: maxdata = atoi(optarg);
185: break;
186: case 'n':
187: fancy = 0;
188: break;
1.17 deraadt 189: case 'p':
190: pid = atoi(optarg);
191: break;
1.55 otto 192: case 'r':
193: resolv = 1;
194: break;
1.1 deraadt 195: case 'R':
196: timestamp = 2; /* relative timestamp */
197: break;
198: case 'T':
199: timestamp = 1;
200: break;
201: case 't':
202: trpoints = getpoints(optarg);
203: if (trpoints < 0)
204: errx(1, "unknown trace point in %s", optarg);
205: break;
1.31 tedu 206: case 'x':
207: iohex = 1;
208: break;
209: case 'X':
210: iohex = 2;
211: break;
1.1 deraadt 212: default:
213: usage();
214: }
1.5 deraadt 215: if (argc > optind)
1.1 deraadt 216: usage();
217:
1.37 tedu 218: m = malloc(size = 1025);
1.1 deraadt 219: if (m == NULL)
1.37 tedu 220: err(1, NULL);
1.1 deraadt 221: if (!freopen(tracefile, "r", stdin))
222: err(1, "%s", tracefile);
223: while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
1.17 deraadt 224: silent = 0;
1.59 otto 225: if (pe_size == 0)
226: mappidtoemul(ktr_header.ktr_pid, current);
1.17 deraadt 227: if (pid != -1 && pid != ktr_header.ktr_pid)
228: silent = 1;
229: if (silent == 0 && trpoints & (1<<ktr_header.ktr_type))
1.1 deraadt 230: dumpheader(&ktr_header);
1.37 tedu 231: ktrlen = ktr_header.ktr_len;
1.1 deraadt 232: if (ktrlen > size) {
1.23 tedu 233: void *newm;
234:
235: newm = realloc(m, ktrlen+1);
236: if (newm == NULL)
1.37 tedu 237: err(1, NULL);
1.23 tedu 238: m = newm;
1.1 deraadt 239: size = ktrlen;
240: }
241: if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
242: errx(1, "data too short");
1.17 deraadt 243: if (silent)
244: continue;
1.1 deraadt 245: if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
246: continue;
1.59 otto 247: current = findemul(ktr_header.ktr_pid);
1.1 deraadt 248: switch (ktr_header.ktr_type) {
249: case KTR_SYSCALL:
250: ktrsyscall((struct ktr_syscall *)m);
251: break;
252: case KTR_SYSRET:
253: ktrsysret((struct ktr_sysret *)m);
254: break;
255: case KTR_NAMEI:
256: ktrnamei(m, ktrlen);
257: break;
258: case KTR_GENIO:
259: ktrgenio((struct ktr_genio *)m, ktrlen);
260: break;
261: case KTR_PSIG:
262: ktrpsig((struct ktr_psig *)m);
263: break;
264: case KTR_CSW:
265: ktrcsw((struct ktr_csw *)m);
266: break;
267: case KTR_EMUL:
268: ktremul(m, ktrlen);
1.59 otto 269: mappidtoemul(ktr_header.ktr_pid, current);
1.1 deraadt 270: break;
1.55 otto 271: case KTR_STRUCT:
272: ktrstruct(m, ktrlen);
273: break;
1.1 deraadt 274: }
275: if (tail)
276: (void)fflush(stdout);
277: }
1.12 espie 278: exit(0);
1.1 deraadt 279: }
280:
1.59 otto 281: static void
282: mappidtoemul(pid_t pid, struct emulation *emul)
283: {
284: size_t i;
285: struct pid_emul *tmp;
286:
287: for (i = 0; i < pe_size; i++) {
288: if (pe_table[i].p == pid) {
289: pe_table[i].e = emul;
290: return;
291: }
292: }
293: tmp = realloc(pe_table, (pe_size + 1) * sizeof(*pe_table));
294: if (tmp == NULL)
295: err(1, NULL);
296: pe_table = tmp;
297: pe_table[pe_size].p = pid;
298: pe_table[pe_size].e = emul;
299: pe_size++;
300: }
301:
302: static struct emulation*
303: findemul(pid_t pid)
304: {
305: size_t i;
306:
307: for (i = 0; i < pe_size; i++)
308: if (pe_table[i].p == pid)
309: return pe_table[i].e;
1.60 otto 310: return def_emul;
1.59 otto 311: }
312:
1.12 espie 313: static int
1.37 tedu 314: fread_tail(void *buf, size_t size, size_t num)
1.1 deraadt 315: {
316: int i;
317:
318: while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
319: (void)sleep(1);
320: clearerr(stdin);
321: }
322: return (i);
323: }
324:
1.12 espie 325: static void
1.17 deraadt 326: dumpheader(struct ktr_header *kth)
1.1 deraadt 327: {
1.17 deraadt 328: static struct timeval prevtime;
1.1 deraadt 329: char unknown[64], *type;
330: struct timeval temp;
331:
332: switch (kth->ktr_type) {
333: case KTR_SYSCALL:
334: type = "CALL";
335: break;
336: case KTR_SYSRET:
337: type = "RET ";
338: break;
339: case KTR_NAMEI:
340: type = "NAMI";
341: break;
342: case KTR_GENIO:
343: type = "GIO ";
344: break;
345: case KTR_PSIG:
346: type = "PSIG";
347: break;
348: case KTR_CSW:
349: type = "CSW";
350: break;
351: case KTR_EMUL:
352: type = "EMUL";
353: break;
1.55 otto 354: case KTR_STRUCT:
355: type = "STRU";
356: break;
1.1 deraadt 357: default:
1.17 deraadt 358: (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)",
359: kth->ktr_type);
1.1 deraadt 360: type = unknown;
361: }
362:
1.16 mpech 363: (void)printf("%6ld %-8.*s ", (long)kth->ktr_pid, MAXCOMLEN,
364: kth->ktr_comm);
1.1 deraadt 365: if (timestamp) {
366: if (timestamp == 2) {
367: timersub(&kth->ktr_time, &prevtime, &temp);
368: prevtime = kth->ktr_time;
369: } else
370: temp = kth->ktr_time;
371: (void)printf("%ld.%06ld ", temp.tv_sec, temp.tv_usec);
372: }
373: (void)printf("%s ", type);
374: }
375:
1.12 espie 376: static void
1.17 deraadt 377: ioctldecode(u_long cmd)
1.2 deraadt 378: {
379: char dirbuf[4], *dir = dirbuf;
380:
1.6 deraadt 381: if (cmd & IOC_IN)
382: *dir++ = 'W';
1.2 deraadt 383: if (cmd & IOC_OUT)
384: *dir++ = 'R';
385: *dir = '\0';
386:
1.33 tedu 387: printf(decimal ? ",_IO%s('%c',%lu" : ",_IO%s('%c',%#lx",
388: dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1.2 deraadt 389: if ((cmd & IOC_VOID) == 0)
1.34 tedu 390: printf(decimal ? ",%lu)" : ",%#lx)", (cmd >> 16) & 0xff);
1.2 deraadt 391: else
392: printf(")");
393: }
1.1 deraadt 394:
1.52 otto 395: static void
396: ptracedecode(void)
397: {
398: if (*ap >= 0 && *ap <
399: sizeof(ptrace_ops) / sizeof(ptrace_ops[0]))
400: (void)printf("%s", ptrace_ops[*ap]);
401: else switch(*ap) {
402: #ifdef PT_GETFPREGS
403: case PT_GETFPREGS:
404: (void)printf("PT_GETFPREGS");
405: break;
406: #endif
407: case PT_GETREGS:
408: (void)printf("PT_GETREGS");
409: break;
410: #ifdef PT_SETFPREGS
411: case PT_SETFPREGS:
412: (void)printf("PT_SETFPREGS");
413: break;
414: #endif
415: case PT_SETREGS:
416: (void)printf("PT_SETREGS");
417: break;
418: #ifdef PT_STEP
419: case PT_STEP:
420: (void)printf("PT_STEP");
421: break;
422: #endif
423: #ifdef PT_WCOOKIE
424: case PT_WCOOKIE:
425: (void)printf("PT_WCOOKIE");
426: break;
427: #endif
428: default:
429: (void)printf("%ld", (long)*ap);
430: break;
431: }
432: sep = ',';
433: ap++;
434: narg--;
435: }
436:
437: static void
438: pn(void (*f)(int))
439: {
440: if (sep)
441: (void)putchar(sep);
442: if (fancy && f != NULL)
443: f((int)*ap);
444: else if (decimal)
445: (void)printf("%ld", (long)*ap);
446: else
447: (void)printf("%#lx", (long)*ap);
448: ap++;
449: narg--;
450: sep = ',';
451: }
452:
453: #ifdef __LP64__
454: #define plln() pn(NULL)
455: #elif _BYTE_ORDER == _LITTLE_ENDIAN
456: static void
457: plln(void)
458: {
459: long long val = ((long long)*ap) & 0xffffffff;
460: ap++;
461: val |= ((long long)*ap) << 32;
462: ap++;
463: narg -= 2;
464: if (sep)
465: (void)putchar(sep);
466: if (decimal)
467: (void)printf("%lld", val);
468: else
469: (void)printf("%#llx", val);
470: sep = ',';
471: }
472: #else
473: static void
474: plln(void)
475: {
476: long long val = ((long long)*ap) << 32;
477: ap++;
478: val |= ((long long)*ap) & 0xffffffff;
479: ap++;
480: narg -= 2;
481: if (sep)
482: (void)putchar(sep);
483: if (decimal)
484: (void)printf("%lld", val);
485: else
486: (void)printf("%#llx", val);
487: sep = ',';
488: }
489: #endif
1.51 otto 490:
1.12 espie 491: static void
1.17 deraadt 492: ktrsyscall(struct ktr_syscall *ktr)
1.1 deraadt 493: {
1.52 otto 494: narg = ktr->ktr_argsize / sizeof(register_t);
495: sep = '\0';
1.1 deraadt 496:
497: if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0)
498: (void)printf("[%d]", ktr->ktr_code);
499: else
500: (void)printf("%s", current->sysnames[ktr->ktr_code]);
501: ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
1.27 mickey 502: (void)putchar('(');
1.52 otto 503:
1.54 otto 504: if (current != &emulations[0])
505: goto nonnative;
506:
1.52 otto 507: switch (ktr->ktr_code) {
508: case SYS_ioctl: {
509: const char *cp;
510:
511: pn(NULL);
512: if (!fancy)
513: break;
514: if ((cp = ioctlname(*ap)) != NULL)
515: (void)printf(",%s", cp);
516: else
517: ioctldecode(*ap);
518: ap++;
519: narg--;
520: break;
521: }
522: case SYS___sysctl: {
1.62 ! otto 523: const char *s;
! 524: int *np, n, i, *top;
1.52 otto 525:
526: if (!fancy)
527: break;
528: n = ap[1];
529: if (n > CTL_MAXNAME)
530: n = CTL_MAXNAME;
1.62 ! otto 531: np = top = (int *)(ap + 6);
! 532: for (i = 0; n--; np++, i++) {
1.52 otto 533: if (sep)
534: putchar(sep);
1.62 ! otto 535: if (resolv && (s = kresolvsysctl(i, top, *np)) != NULL)
! 536: printf("%s", s);
! 537: else
! 538: printf("%d", *np);
1.52 otto 539: sep = '.';
1.1 deraadt 540: }
1.52 otto 541:
542: sep = ',';
543: ap += 2;
544: narg -= 2;
545: break;
546: }
547: case SYS_ptrace:
548: if (!fancy)
549: break;
550: ptracedecode();
551: break;
552: case SYS_access:
553: pn(NULL);
554: pn(accessmodename);
555: break;
556: case SYS_chmod:
557: case SYS_fchmod:
1.61 matthew 558: pn(NULL);
1.52 otto 559: pn(modename);
560: break;
561: case SYS_fcntl: {
562: int cmd;
563: int arg;
564: pn(NULL);
565: if (!fancy)
566: break;
567: cmd = ap[0];
568: arg = ap[1];
569: (void)putchar(',');
570: fcntlcmdname(cmd, arg);
571: ap += 2;
572: narg -= 2;
573: break;
574: }
575: case SYS_flock:
576: pn(NULL);
577: pn(flockname);
578: break;
579: case SYS_getrlimit:
580: case SYS_setrlimit:
581: pn(rlimitname);
582: break;
583: case SYS_getsockopt:
584: case SYS_setsockopt: {
585: int level;
586:
587: pn(NULL);
588: level = *ap;
589: pn(sockoptlevelname);
590: if (level == SOL_SOCKET)
591: pn(sockoptname);
592: break;
593: }
594: case SYS_kill:
595: pn(NULL);
596: pn(signame);
597: break;
598: case SYS_lseek:
599: pn(NULL);
600: /* skip padding */
601: ap++;
602: narg--;
603: plln();
604: pn(whencename);
605: break;
606: case SYS_madvise:
607: pn(NULL);
608: pn(NULL);
609: pn(madvisebehavname);
610: break;
611: case SYS_minherit:
612: pn(NULL);
613: pn(NULL);
614: pn(minheritname);
615: break;
616: case SYS_mlockall:
617: pn(mlockallname);
618: break;
619: case SYS_mmap:
620: pn(NULL);
621: pn(NULL);
622: pn(mmapprotname);
623: pn(mmapflagsname);
624: pn(NULL);
625: /* skip padding */
626: ap++;
627: narg--;
628: plln();
629: break;
630: case SYS_mprotect:
631: pn(NULL);
632: pn(NULL);
633: pn(mmapprotname);
634: break;
635: case SYS_mquery:
636: pn(NULL);
637: pn(NULL);
638: pn(mmapprotname);
639: pn(mmapflagsname);
640: pn(NULL);
641: /* skip padding */
642: ap++;
643: narg--;
644: plln();
645: break;
646: case SYS_msync:
647: pn(NULL);
648: pn(NULL);
649: pn(msyncflagsname);
650: break;
651: case SYS_msgctl:
652: pn(NULL);
653: pn(shmctlname);
654: break;
655: case SYS_open: {
656: int flags;
657: int mode;
658:
659: pn(NULL);
660: if (!fancy)
661: break;
662: flags = ap[0];
663: mode = ap[1];
664: (void)putchar(',');
665: flagsandmodename(flags, mode);
666: ap += 2;
667: narg -= 2;
668: break;
669: }
670: case SYS_pread:
671: case SYS_preadv:
672: case SYS_pwrite:
673: case SYS_pwritev:
674: pn(NULL);
675: pn(NULL);
676: pn(NULL);
677: /* skip padding */
678: ap++;
679: narg--;
680: plln();
681: break;
682: case SYS_recvmsg:
683: case SYS_sendmsg:
684: pn(NULL);
685: pn(NULL);
686: pn(sendrecvflagsname);
687: break;
688: case SYS_recvfrom:
689: case SYS_sendto:
690: pn(NULL);
691: pn(NULL);
692: pn(NULL);
693: pn(sendrecvflagsname);
694: break;
695: case SYS___semctl:
696: pn(NULL);
697: pn(NULL);
698: pn(semctlname);
699: break;
700: case SYS_semget:
701: pn(NULL);
702: pn(NULL);
703: pn(semgetname);
704: break;
705: case SYS_shmat:
706: pn(NULL);
707: pn(NULL);
708: pn(shmatname);
709: break;
710: case SYS_shmctl:
711: pn(NULL);
712: pn(shmctlname);
713: break;
714: case SYS_sigaction:
715: pn(signame);
716: break;
717: case SYS_sigprocmask:
718: pn(sigprocmaskhowname);
719: break;
720: case SYS_socket: {
721: int sockdomain = *ap;
722:
723: pn(sockdomainname);
724: pn(socktypename);
725: if (sockdomain == PF_INET || sockdomain == PF_INET6)
726: pn(sockipprotoname);
727: break;
728: }
729: case SYS_socketpair:
730: pn(sockdomainname);
731: pn(socktypename);
732: break;
733: case SYS_truncate:
734: case SYS_ftruncate:
735: pn(NULL);
736: /* skip padding */
737: ap++;
738: narg--;
739: plln();
740: break;
741: case SYS_wait4:
742: pn(NULL);
743: pn(NULL);
744: pn(wait4optname);
745: break;
1.61 matthew 746: case SYS_faccessat:
747: pn(atfd);
748: pn(NULL);
749: pn(accessmodename);
750: pn(atflagsname);
751: break;
752: case SYS_fchmodat:
753: pn(atfd);
754: pn(NULL);
755: pn(modename);
756: pn(atflagsname);
757: break;
758: case SYS_fchownat:
759: pn(atfd);
760: pn(NULL);
761: pn(NULL);
762: pn(NULL);
763: pn(atflagsname);
764: break;
765: case SYS_fstatat:
766: pn(atfd);
767: pn(NULL);
768: pn(NULL);
769: pn(atflagsname);
770: break;
771: case SYS_linkat:
772: pn(atfd);
773: pn(NULL);
774: pn(atfd);
775: pn(NULL);
776: pn(atflagsname);
777: break;
778: case SYS_mkdirat:
779: case SYS_mkfifoat:
780: case SYS_mknodat:
781: pn(atfd);
782: pn(NULL);
783: pn(modename);
784: break;
785: case SYS_openat: {
786: int flags;
787: int mode;
788:
789: pn(atfd);
790: pn(NULL);
791: if (!fancy)
792: break;
793: flags = ap[0];
794: mode = ap[1];
795: (void)putchar(',');
796: flagsandmodename(flags, mode);
797: ap += 2;
798: narg -= 2;
799: break;
800: }
801: case SYS_readlinkat:
802: pn(atfd);
803: break;
804: case SYS_renameat:
805: pn(atfd);
806: pn(NULL);
807: pn(atfd);
808: break;
809: case SYS_symlinkat:
810: pn(NULL);
811: pn(atfd);
812: break;
813: case SYS_unlinkat:
814: pn(atfd);
815: pn(NULL);
816: pn(atflagsname);
817: break;
818: case SYS_utimensat:
819: pn(atfd);
820: pn(NULL);
821: pn(NULL);
822: pn(atflagsname);
823: break;
1.52 otto 824: }
825:
1.54 otto 826: nonnative:
1.52 otto 827: while (narg) {
828: if (sep)
829: putchar(sep);
830: if (decimal)
831: (void)printf("%ld", (long)*ap);
832: else
833: (void)printf("%#lx", (long)*ap);
834: sep = ',';
835: ap++;
836: narg--;
1.1 deraadt 837: }
1.27 mickey 838: (void)printf(")\n");
1.62 ! otto 839: }
! 840:
! 841: static struct ctlname topname[] = CTL_NAMES;
! 842: static struct ctlname kernname[] = CTL_KERN_NAMES;
! 843: static struct ctlname vmname[] = CTL_VM_NAMES;
! 844: static struct ctlname fsname[] = CTL_FS_NAMES;
! 845: static struct ctlname netname[] = CTL_NET_NAMES;
! 846: static struct ctlname hwname[] = CTL_HW_NAMES;
! 847: static struct ctlname username[] = CTL_USER_NAMES;
! 848: static struct ctlname debugname[CTL_DEBUG_MAXID];
! 849: static struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES;
! 850: static struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES;
! 851: static struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES;
! 852: static struct ctlname ttysname[] = CTL_KERN_TTY_NAMES;
! 853: static struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES;
! 854: static struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES;
! 855: static struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES;
! 856: static struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES;
! 857: #ifdef CTL_MACHDEP_NAMES
! 858: static struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
! 859: #endif
! 860: static struct ctlname ddbname[] = CTL_DDB_NAMES;
! 861:
! 862: #ifndef nitems
! 863: #define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
! 864: #endif
! 865:
! 866: #define SETNAME(name) do { names = (name); limit = nitems(name); } while (0)
! 867:
! 868: static const char *
! 869: kresolvsysctl(int depth, int *top, int idx)
! 870: {
! 871: struct ctlname *names;
! 872: size_t limit;
! 873:
! 874: names = NULL;
! 875:
! 876: switch (depth) {
! 877: case 0:
! 878: SETNAME(topname);
! 879: break;
! 880: case 1:
! 881: switch (top[0]) {
! 882: case CTL_KERN:
! 883: SETNAME(kernname);
! 884: break;
! 885: case CTL_VM:
! 886: SETNAME(vmname);
! 887: break;
! 888: case CTL_FS:
! 889: SETNAME(fsname);
! 890: break;
! 891: case CTL_NET:
! 892: SETNAME(netname);
! 893: break;
! 894: case CTL_DEBUG:
! 895: SETNAME(debugname);
! 896: break;
! 897: case CTL_HW:
! 898: SETNAME(hwname);
! 899: break;
! 900: #ifdef CTL_MACHDEP_NAMES
! 901: case CTL_MACHDEP:
! 902: SETNAME(machdepname);
! 903: break;
! 904: #endif
! 905: case CTL_USER:
! 906: SETNAME(username);
! 907: break;
! 908: case CTL_DDB:
! 909: SETNAME(ddbname);
! 910: break;
! 911: }
! 912: break;
! 913: case 2:
! 914: switch (top[0]) {
! 915: case CTL_KERN:
! 916: switch (top[1]) {
! 917: case KERN_MALLOCSTATS:
! 918: SETNAME(kernmallocname);
! 919: break;
! 920: case KERN_FORKSTAT:
! 921: SETNAME(forkstatname);
! 922: break;
! 923: case KERN_NCHSTATS:
! 924: SETNAME(nchstatsname);
! 925: break;
! 926: case KERN_TTY:
! 927: SETNAME(ttysname);
! 928: break;
! 929: case KERN_SEMINFO:
! 930: SETNAME(semname);
! 931: break;
! 932: case KERN_SHMINFO:
! 933: SETNAME(shmname);
! 934: break;
! 935: case KERN_WATCHDOG:
! 936: SETNAME(watchdogname);
! 937: break;
! 938: case KERN_TIMECOUNTER:
! 939: SETNAME(tcname);
! 940: break;
! 941: }
! 942: }
! 943: break;
! 944: }
! 945: if (names != NULL && idx > 0 && idx < limit)
! 946: return (names[idx].ctl_name);
! 947: return (NULL);
1.1 deraadt 948: }
949:
1.12 espie 950: static void
1.17 deraadt 951: ktrsysret(struct ktr_sysret *ktr)
1.1 deraadt 952: {
1.50 deraadt 953: register_t ret = ktr->ktr_retval;
1.12 espie 954: int error = ktr->ktr_error;
955: int code = ktr->ktr_code;
1.1 deraadt 956:
957: if (code >= current->nsysnames || code < 0)
958: (void)printf("[%d] ", code);
1.59 otto 959: else {
1.1 deraadt 960: (void)printf("%s ", current->sysnames[code]);
1.59 otto 961: if (ret > 0 && (strcmp(current->sysnames[code], "fork") == 0 ||
962: strcmp(current->sysnames[code], "vfork") == 0 ||
963: strcmp(current->sysnames[code], "rfork") == 0 ||
964: strcmp(current->sysnames[code], "clone") == 0))
965: mappidtoemul(ret, current);
966: }
1.1 deraadt 967:
968: if (error == 0) {
969: if (fancy) {
1.50 deraadt 970: (void)printf("%ld", (long)ret);
1.1 deraadt 971: if (ret < 0 || ret > 9)
1.50 deraadt 972: (void)printf("/%#lx", (long)ret);
1.1 deraadt 973: } else {
974: if (decimal)
1.50 deraadt 975: (void)printf("%ld", (long)ret);
1.1 deraadt 976: else
1.50 deraadt 977: (void)printf("%#lx", (long)ret);
1.1 deraadt 978: }
979: } else if (error == ERESTART)
980: (void)printf("RESTART");
981: else if (error == EJUSTRETURN)
982: (void)printf("JUSTRETURN");
983: else {
984: (void)printf("-1 errno %d", ktr->ktr_error);
985: if (fancy)
986: (void)printf(" %s", strerror(ktr->ktr_error));
987: }
988: (void)putchar('\n');
989: }
990:
1.12 espie 991: static void
1.37 tedu 992: ktrnamei(const char *cp, size_t len)
1.1 deraadt 993: {
1.37 tedu 994: (void)printf("\"%.*s\"\n", (int)len, cp);
1.1 deraadt 995: }
996:
1.12 espie 997: static void
1.37 tedu 998: ktremul(char *cp, size_t len)
1.1 deraadt 999: {
1000: char name[1024];
1001:
1002: if (len >= sizeof(name))
1003: errx(1, "Emulation name too long");
1004:
1005: strncpy(name, cp, len);
1006: name[len] = '\0';
1007: (void)printf("\"%s\"\n", name);
1008:
1009: setemul(name);
1010: }
1011:
1.12 espie 1012: static void
1.37 tedu 1013: ktrgenio(struct ktr_genio *ktr, size_t len)
1.1 deraadt 1014: {
1.37 tedu 1015: unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
1016: int i, j;
1017: size_t datalen = len - sizeof(struct ktr_genio);
1.12 espie 1018: static int screenwidth = 0;
1.31 tedu 1019: int col = 0, width, bpl;
1.32 tedu 1020: unsigned char visbuf[5], *cp, c;
1.1 deraadt 1021:
1022: if (screenwidth == 0) {
1023: struct winsize ws;
1024:
1025: if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1026: ws.ws_col > 8)
1027: screenwidth = ws.ws_col;
1028: else
1029: screenwidth = 80;
1030: }
1.37 tedu 1031: printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1.1 deraadt 1032: ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
1.58 otto 1033: if (maxdata == 0)
1034: return;
1035: if (datalen > maxdata)
1.1 deraadt 1036: datalen = maxdata;
1.31 tedu 1037: if (iohex && !datalen)
1038: return;
1039: if (iohex == 1) {
1040: putchar('\t');
1041: col = 8;
1042: for (i = 0; i < datalen; i++) {
1.35 tedu 1043: printf("%02x", dp[i]);
1.31 tedu 1044: col += 3;
1045: if (i < datalen - 1) {
1046: if (col + 3 > screenwidth) {
1047: printf("\n\t");
1048: col = 8;
1049: } else
1050: putchar(' ');
1051: }
1052: }
1053: putchar('\n');
1054: return;
1055: }
1056: if (iohex == 2) {
1057: bpl = (screenwidth - 13)/4;
1058: if (bpl <= 0)
1059: bpl = 1;
1060: for (i = 0; i < datalen; i += bpl) {
1061: printf(" %04x: ", i);
1062: for (j = 0; j < bpl; j++) {
1063: if (i+j >= datalen)
1064: printf(" ");
1065: else
1.35 tedu 1066: printf("%02x ", dp[i+j]);
1.31 tedu 1067: }
1068: putchar(' ');
1069: for (j = 0; j < bpl; j++) {
1070: if (i+j >= datalen)
1071: break;
1072: c = dp[i+j];
1073: if (!isprint(c))
1074: c = '.';
1075: putchar(c);
1076: }
1077: putchar('\n');
1078: }
1079: return;
1080: }
1.1 deraadt 1081: (void)printf(" \"");
1082: col = 8;
1083: for (; datalen > 0; datalen--, dp++) {
1.31 tedu 1084: (void)vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
1.1 deraadt 1085: cp = visbuf;
1.17 deraadt 1086:
1.1 deraadt 1087: /*
1088: * Keep track of printables and
1089: * space chars (like fold(1)).
1090: */
1091: if (col == 0) {
1092: (void)putchar('\t');
1093: col = 8;
1094: }
1.17 deraadt 1095: switch (*cp) {
1.1 deraadt 1096: case '\n':
1097: col = 0;
1098: (void)putchar('\n');
1099: continue;
1100: case '\t':
1101: width = 8 - (col&07);
1102: break;
1103: default:
1104: width = strlen(cp);
1105: }
1106: if (col + width > (screenwidth-2)) {
1107: (void)printf("\\\n\t");
1108: col = 8;
1109: }
1110: col += width;
1111: do {
1112: (void)putchar(*cp++);
1113: } while (*cp);
1114: }
1115: if (col == 0)
1116: (void)printf(" ");
1117: (void)printf("\"\n");
1118: }
1119:
1.12 espie 1120: static void
1.17 deraadt 1121: ktrpsig(struct ktr_psig *psig)
1.1 deraadt 1122: {
1123: (void)printf("SIG%s ", sys_signame[psig->signo]);
1124: if (psig->action == SIG_DFL)
1.14 deraadt 1125: (void)printf("SIG_DFL code %d", psig->code);
1.1 deraadt 1126: else
1.14 deraadt 1127: (void)printf("caught handler=0x%lx mask=0x%x",
1128: (u_long)psig->action, psig->mask);
1129: switch (psig->signo) {
1130: case SIGSEGV:
1131: case SIGILL:
1132: case SIGBUS:
1133: case SIGFPE:
1134: printf(" addr=%p trapno=%d", psig->si.si_addr,
1135: psig->si.si_trapno);
1136: break;
1137: default:
1138: break;
1139: }
1140: printf("\n");
1.1 deraadt 1141: }
1142:
1.12 espie 1143: static void
1.17 deraadt 1144: ktrcsw(struct ktr_csw *cs)
1.1 deraadt 1145: {
1146: (void)printf("%s %s\n", cs->out ? "stop" : "resume",
1147: cs->user ? "user" : "kernel");
1148: }
1149:
1.55 otto 1150:
1151:
1152: void
1153: ktrsockaddr(struct sockaddr *sa)
1154: {
1155: /*
1156: TODO: Support additional address families
1157: #include <netnatm/natm.h>
1158: struct sockaddr_natm *natm;
1159: #include <netsmb/netbios.h>
1160: struct sockaddr_nb *nb;
1161: */
1162: char addr[64];
1163:
1164: /*
1165: * note: ktrstruct() has already verified that sa points to a
1166: * buffer at least sizeof(struct sockaddr) bytes long and exactly
1167: * sa->sa_len bytes long.
1168: */
1169: printf("struct sockaddr { ");
1170: sockfamilyname(sa->sa_family);
1171: printf(", ");
1172:
1173: #define check_sockaddr_len(n) \
1174: if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \
1175: printf("invalid"); \
1176: break; \
1177: }
1178:
1179: switch(sa->sa_family) {
1180: case AF_INET: {
1181: struct sockaddr_in *sa_in;
1182:
1183: sa_in = (struct sockaddr_in *)sa;
1184: check_sockaddr_len(in);
1185: inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);
1186: printf("%s:%u", addr, ntohs(sa_in->sin_port));
1187: break;
1188: }
1189: case AF_INET6: {
1190: struct sockaddr_in6 *sa_in6;
1191:
1192: sa_in6 = (struct sockaddr_in6 *)sa;
1193: check_sockaddr_len(in6);
1194: inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);
1195: printf("[%s]:%u", addr, htons(sa_in6->sin6_port));
1196: break;
1197: }
1198: #ifdef IPX
1199: case AF_IPX: {
1200: struct sockaddr_ipx *sa_ipx;
1201:
1202: sa_ipx = (struct sockaddr_ipx *)sa;
1203: check_sockaddr_len(ipx);
1204: /* XXX wish we had ipx_ntop */
1205: printf("%s", ipx_ntoa(sa_ipx->sipx_addr));
1206: break;
1207: }
1208: #endif
1209: case AF_UNIX: {
1210: struct sockaddr_un *sa_un;
1211:
1212: sa_un = (struct sockaddr_un *)sa;
1213: if (sa_un->sun_len <= sizeof(sa_un->sun_len) +
1214: sizeof(sa_un->sun_family)) {
1215: printf("invalid");
1216: break;
1217: }
1218: printf("\"%.*s\"", (int)(sa_un->sun_len -
1219: sizeof(sa_un->sun_len) - sizeof(sa_un->sun_family)),
1220: sa_un->sun_path);
1221: break;
1222: }
1223: default:
1224: printf("unknown address family");
1225: }
1226: printf(" }\n");
1227: }
1228:
1229: void
1230: ktrstat(struct stat *statp)
1231: {
1232: char mode[12], timestr[PATH_MAX + 4];
1233: struct passwd *pwd;
1234: struct group *grp;
1235: struct tm *tm;
1236:
1237: /*
1238: * note: ktrstruct() has already verified that statp points to a
1239: * buffer exactly sizeof(struct stat) bytes long.
1240: */
1241: printf("struct stat {");
1242: strmode(statp->st_mode, mode);
1243: printf("dev=%d, ino=%u, mode=%s, nlink=%u, ",
1244: statp->st_dev, statp->st_ino, mode, statp->st_nlink);
1245: if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1246: printf("uid=%u, ", statp->st_uid);
1247: else
1248: printf("uid=\"%s\", ", pwd->pw_name);
1249: if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1250: printf("gid=%u, ", statp->st_gid);
1251: else
1252: printf("gid=\"%s\", ", grp->gr_name);
1253: printf("rdev=%d, ", statp->st_rdev);
1254: printf("atime=");
1255: if (resolv == 0)
1256: printf("%jd", (intmax_t)statp->st_atim.tv_sec);
1257: else {
1258: tm = localtime(&statp->st_atim.tv_sec);
1259: (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1260: printf("\"%s\"", timestr);
1261: }
1262: if (statp->st_atim.tv_nsec != 0)
1263: printf(".%09ld, ", statp->st_atim.tv_nsec);
1264: else
1265: printf(", ");
1266: printf("stime=");
1267: if (resolv == 0)
1268: printf("%jd", (intmax_t)statp->st_mtim.tv_sec);
1269: else {
1270: tm = localtime(&statp->st_mtim.tv_sec);
1271: (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1272: printf("\"%s\"", timestr);
1273: }
1274: if (statp->st_mtim.tv_nsec != 0)
1275: printf(".%09ld, ", statp->st_mtim.tv_nsec);
1276: else
1277: printf(", ");
1278: printf("ctime=");
1279: if (resolv == 0)
1280: printf("%jd", (intmax_t)statp->st_ctim.tv_sec);
1281: else {
1282: tm = localtime(&statp->st_ctim.tv_sec);
1283: (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1284: printf("\"%s\"", timestr);
1285: }
1286: if (statp->st_ctim.tv_nsec != 0)
1287: printf(".%09ld, ", statp->st_ctim.tv_nsec);
1288: else
1289: printf(", ");
1290: printf("size=%lld, blocks=%lld, blksize=%u, flags=0x%x, gen=0x%x",
1291: statp->st_size, statp->st_blocks, statp->st_blksize,
1292: statp->st_flags, statp->st_gen);
1293: printf(" }\n");
1294: }
1295:
1296: void
1297: ktrstruct(char *buf, size_t buflen)
1298: {
1299: char *name, *data;
1300: size_t namelen, datalen;
1301: int i;
1302: struct stat sb;
1303: struct sockaddr_storage ss;
1304:
1305: for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0';
1306: ++namelen)
1307: /* nothing */;
1308: if (namelen == buflen)
1309: goto invalid;
1310: if (name[namelen] != '\0')
1311: goto invalid;
1312: data = buf + namelen + 1;
1313: datalen = buflen - namelen - 1;
1314: if (datalen == 0)
1315: goto invalid;
1316: /* sanity check */
1317: for (i = 0; i < namelen; ++i)
1318: if (!isalpha((unsigned char)name[i]))
1319: goto invalid;
1320: if (strcmp(name, "stat") == 0) {
1321: if (datalen != sizeof(struct stat))
1322: goto invalid;
1323: memcpy(&sb, data, datalen);
1324: ktrstat(&sb);
1325: } else if (strcmp(name, "sockaddr") == 0) {
1326: if (datalen > sizeof(ss))
1327: goto invalid;
1328: memcpy(&ss, data, datalen);
1329: if ((ss.ss_family != AF_UNIX &&
1330: datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len)
1331: goto invalid;
1332: ktrsockaddr((struct sockaddr *)&ss);
1333: } else {
1.57 otto 1334: printf("unknown structure %s\n", name);
1.55 otto 1335: }
1336: return;
1337: invalid:
1338: printf("invalid record\n");
1339: }
1340:
1.12 espie 1341: static void
1.17 deraadt 1342: usage(void)
1.1 deraadt 1343: {
1344:
1.19 mickey 1345: extern char *__progname;
1346: fprintf(stderr, "usage: %s "
1.55 otto 1347: "[-dlnRrTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n"
1.40 sobrado 1348: "%*s[-t [ceinsw]]\n",
1.51 otto 1349: __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
1.1 deraadt 1350: exit(1);
1351: }
1352:
1.12 espie 1353: static void
1.17 deraadt 1354: setemul(const char *name)
1.1 deraadt 1355: {
1356: int i;
1.17 deraadt 1357:
1.1 deraadt 1358: for (i = 0; emulations[i].name != NULL; i++)
1359: if (strcmp(emulations[i].name, name) == 0) {
1360: current = &emulations[i];
1361: return;
1362: }
1363: warnx("Emulation `%s' unknown", name);
1.61 matthew 1364: }
1365:
1366: static void
1367: atfd(int fd)
1368: {
1369: if (fd == AT_FDCWD)
1370: (void)printf("AT_FDCWD");
1371: else if (decimal)
1372: (void)printf("%d", fd);
1373: else
1374: (void)printf("%#x", fd);
1.1 deraadt 1375: }