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