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