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