Annotation of src/usr.bin/kdump/kdump.c, Revision 1.79
1.79 ! deraadt 1: /* $OpenBSD: kdump.c,v 1.78 2013/04/15 16:47:14 guenther 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.79 ! deraadt 388: printf("%lld.%06ld ", (long long)temp.tv_sec,
! 389: temp.tv_nsec / 1000);
1.1 deraadt 390: }
391: (void)printf("%s ", type);
392: }
393:
1.12 espie 394: static void
1.17 deraadt 395: ioctldecode(u_long cmd)
1.2 deraadt 396: {
397: char dirbuf[4], *dir = dirbuf;
398:
1.6 deraadt 399: if (cmd & IOC_IN)
400: *dir++ = 'W';
1.2 deraadt 401: if (cmd & IOC_OUT)
402: *dir++ = 'R';
403: *dir = '\0';
404:
1.33 tedu 405: printf(decimal ? ",_IO%s('%c',%lu" : ",_IO%s('%c',%#lx",
406: dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1.2 deraadt 407: if ((cmd & IOC_VOID) == 0)
1.34 tedu 408: printf(decimal ? ",%lu)" : ",%#lx)", (cmd >> 16) & 0xff);
1.2 deraadt 409: else
410: printf(")");
411: }
1.1 deraadt 412:
1.52 otto 413: static void
414: ptracedecode(void)
415: {
416: if (*ap >= 0 && *ap <
417: sizeof(ptrace_ops) / sizeof(ptrace_ops[0]))
418: (void)printf("%s", ptrace_ops[*ap]);
419: else switch(*ap) {
420: #ifdef PT_GETFPREGS
421: case PT_GETFPREGS:
422: (void)printf("PT_GETFPREGS");
423: break;
424: #endif
425: case PT_GETREGS:
426: (void)printf("PT_GETREGS");
427: break;
1.75 guenther 428: #ifdef PT_GETXMMREGS
429: case PT_GETXMMREGS:
430: (void)printf("PT_GETXMMREGS");
431: break;
432: #endif
1.52 otto 433: #ifdef PT_SETFPREGS
434: case PT_SETFPREGS:
435: (void)printf("PT_SETFPREGS");
436: break;
437: #endif
438: case PT_SETREGS:
439: (void)printf("PT_SETREGS");
440: break;
1.75 guenther 441: #ifdef PT_SETXMMREGS
442: case PT_SETXMMREGS:
443: (void)printf("PT_SETXMMREGS");
444: break;
445: #endif
1.52 otto 446: #ifdef PT_STEP
447: case PT_STEP:
448: (void)printf("PT_STEP");
449: break;
450: #endif
451: #ifdef PT_WCOOKIE
452: case PT_WCOOKIE:
453: (void)printf("PT_WCOOKIE");
454: break;
455: #endif
456: default:
457: (void)printf("%ld", (long)*ap);
458: break;
459: }
460: sep = ',';
461: ap++;
462: narg--;
463: }
464:
465: static void
466: pn(void (*f)(int))
467: {
468: if (sep)
469: (void)putchar(sep);
470: if (fancy && f != NULL)
471: f((int)*ap);
472: else if (decimal)
473: (void)printf("%ld", (long)*ap);
474: else
475: (void)printf("%#lx", (long)*ap);
476: ap++;
477: narg--;
478: sep = ',';
479: }
480:
481: #ifdef __LP64__
482: #define plln() pn(NULL)
483: #elif _BYTE_ORDER == _LITTLE_ENDIAN
484: static void
485: plln(void)
486: {
487: long long val = ((long long)*ap) & 0xffffffff;
488: ap++;
489: val |= ((long long)*ap) << 32;
490: ap++;
491: narg -= 2;
492: if (sep)
493: (void)putchar(sep);
494: if (decimal)
495: (void)printf("%lld", val);
496: else
497: (void)printf("%#llx", val);
498: sep = ',';
499: }
500: #else
501: static void
502: plln(void)
503: {
504: long long val = ((long long)*ap) << 32;
505: ap++;
506: val |= ((long long)*ap) & 0xffffffff;
507: ap++;
508: narg -= 2;
509: if (sep)
510: (void)putchar(sep);
511: if (decimal)
512: (void)printf("%lld", val);
513: else
514: (void)printf("%#llx", val);
515: sep = ',';
516: }
517: #endif
1.51 otto 518:
1.12 espie 519: static void
1.17 deraadt 520: ktrsyscall(struct ktr_syscall *ktr)
1.1 deraadt 521: {
1.52 otto 522: narg = ktr->ktr_argsize / sizeof(register_t);
523: sep = '\0';
1.1 deraadt 524:
525: if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0)
526: (void)printf("[%d]", ktr->ktr_code);
527: else
528: (void)printf("%s", current->sysnames[ktr->ktr_code]);
529: ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
1.27 mickey 530: (void)putchar('(');
1.52 otto 531:
1.54 otto 532: if (current != &emulations[0])
533: goto nonnative;
534:
1.52 otto 535: switch (ktr->ktr_code) {
536: case SYS_ioctl: {
537: const char *cp;
538:
539: pn(NULL);
540: if (!fancy)
541: break;
542: if ((cp = ioctlname(*ap)) != NULL)
543: (void)printf(",%s", cp);
544: else
545: ioctldecode(*ap);
546: ap++;
547: narg--;
548: break;
549: }
550: case SYS___sysctl: {
1.62 otto 551: const char *s;
552: int *np, n, i, *top;
1.52 otto 553:
554: if (!fancy)
555: break;
556: n = ap[1];
557: if (n > CTL_MAXNAME)
558: n = CTL_MAXNAME;
1.62 otto 559: np = top = (int *)(ap + 6);
560: for (i = 0; n--; np++, i++) {
1.52 otto 561: if (sep)
562: putchar(sep);
1.62 otto 563: if (resolv && (s = kresolvsysctl(i, top, *np)) != NULL)
564: printf("%s", s);
565: else
566: printf("%d", *np);
1.52 otto 567: sep = '.';
1.1 deraadt 568: }
1.52 otto 569:
570: sep = ',';
571: ap += 2;
572: narg -= 2;
573: break;
574: }
575: case SYS_ptrace:
576: if (!fancy)
577: break;
578: ptracedecode();
579: break;
580: case SYS_access:
581: pn(NULL);
582: pn(accessmodename);
583: break;
584: case SYS_chmod:
585: case SYS_fchmod:
1.61 matthew 586: pn(NULL);
1.52 otto 587: pn(modename);
588: break;
589: case SYS_fcntl: {
590: int cmd;
591: int arg;
592: pn(NULL);
593: if (!fancy)
594: break;
595: cmd = ap[0];
596: arg = ap[1];
597: (void)putchar(',');
598: fcntlcmdname(cmd, arg);
599: ap += 2;
600: narg -= 2;
601: break;
602: }
603: case SYS_flock:
604: pn(NULL);
605: pn(flockname);
606: break;
607: case SYS_getrlimit:
608: case SYS_setrlimit:
609: pn(rlimitname);
610: break;
611: case SYS_getsockopt:
612: case SYS_setsockopt: {
613: int level;
614:
615: pn(NULL);
616: level = *ap;
617: pn(sockoptlevelname);
618: if (level == SOL_SOCKET)
619: pn(sockoptname);
620: break;
621: }
622: case SYS_kill:
623: pn(NULL);
624: pn(signame);
625: break;
626: case SYS_lseek:
627: pn(NULL);
628: /* skip padding */
629: ap++;
630: narg--;
631: plln();
632: pn(whencename);
633: break;
634: case SYS_madvise:
635: pn(NULL);
636: pn(NULL);
637: pn(madvisebehavname);
638: break;
639: case SYS_minherit:
640: pn(NULL);
641: pn(NULL);
642: pn(minheritname);
643: break;
644: case SYS_mlockall:
645: pn(mlockallname);
646: break;
647: case SYS_mmap:
648: pn(NULL);
649: pn(NULL);
650: pn(mmapprotname);
651: pn(mmapflagsname);
652: pn(NULL);
653: /* skip padding */
654: ap++;
655: narg--;
656: plln();
657: break;
658: case SYS_mprotect:
659: pn(NULL);
660: pn(NULL);
661: pn(mmapprotname);
662: break;
663: case SYS_mquery:
664: pn(NULL);
665: pn(NULL);
666: pn(mmapprotname);
667: pn(mmapflagsname);
668: pn(NULL);
669: /* skip padding */
670: ap++;
671: narg--;
672: plln();
673: break;
674: case SYS_msync:
675: pn(NULL);
676: pn(NULL);
677: pn(msyncflagsname);
678: break;
679: case SYS_msgctl:
680: pn(NULL);
681: pn(shmctlname);
682: break;
683: case SYS_open: {
684: int flags;
685: int mode;
686:
687: pn(NULL);
688: if (!fancy)
689: break;
690: flags = ap[0];
691: mode = ap[1];
692: (void)putchar(',');
693: flagsandmodename(flags, mode);
694: ap += 2;
695: narg -= 2;
696: break;
697: }
698: case SYS_pread:
699: case SYS_preadv:
700: case SYS_pwrite:
701: case SYS_pwritev:
702: pn(NULL);
703: pn(NULL);
704: pn(NULL);
705: /* skip padding */
706: ap++;
707: narg--;
708: plln();
709: break;
710: case SYS_recvmsg:
711: case SYS_sendmsg:
712: pn(NULL);
713: pn(NULL);
714: pn(sendrecvflagsname);
715: break;
716: case SYS_recvfrom:
717: case SYS_sendto:
718: pn(NULL);
719: pn(NULL);
720: pn(NULL);
721: pn(sendrecvflagsname);
722: break;
1.77 guenther 723: case SYS_shutdown:
724: pn(NULL);
725: pn(shutdownhowname);
726: break;
1.52 otto 727: case SYS___semctl:
728: pn(NULL);
729: pn(NULL);
730: pn(semctlname);
731: break;
732: case SYS_semget:
733: pn(NULL);
734: pn(NULL);
735: pn(semgetname);
736: break;
737: case SYS_shmat:
738: pn(NULL);
739: pn(NULL);
740: pn(shmatname);
741: break;
742: case SYS_shmctl:
743: pn(NULL);
744: pn(shmctlname);
745: break;
1.64 guenther 746: case SYS_clock_gettime:
747: case SYS_clock_settime:
748: case SYS_clock_getres:
749: pn(clockname);
750: break;
1.77 guenther 751: case SYS_poll:
752: pn(NULL);
753: pn(NULL);
754: pn(polltimeout);
755: break;
1.52 otto 756: case SYS_sigaction:
757: pn(signame);
758: break;
759: case SYS_sigprocmask:
760: pn(sigprocmaskhowname);
1.64 guenther 761: pn(sigset);
762: break;
763: case SYS_sigsuspend:
764: pn(sigset);
1.52 otto 765: break;
766: case SYS_socket: {
767: int sockdomain = *ap;
768:
769: pn(sockdomainname);
770: pn(socktypename);
771: if (sockdomain == PF_INET || sockdomain == PF_INET6)
772: pn(sockipprotoname);
773: break;
774: }
775: case SYS_socketpair:
776: pn(sockdomainname);
777: pn(socktypename);
778: break;
779: case SYS_truncate:
780: case SYS_ftruncate:
781: pn(NULL);
782: /* skip padding */
783: ap++;
784: narg--;
785: plln();
786: break;
787: case SYS_wait4:
788: pn(NULL);
789: pn(NULL);
790: pn(wait4optname);
791: break;
1.77 guenther 792: case SYS_getrusage:
793: pn(rusagewho);
794: break;
1.64 guenther 795: case SYS___thrsleep:
796: pn(NULL);
797: pn(clockname);
798: break;
799: case SYS___thrsigdivert:
800: pn(sigset);
801: break;
1.61 matthew 802: case SYS_faccessat:
803: pn(atfd);
804: pn(NULL);
805: pn(accessmodename);
806: pn(atflagsname);
807: break;
808: case SYS_fchmodat:
809: pn(atfd);
810: pn(NULL);
811: pn(modename);
812: pn(atflagsname);
813: break;
814: case SYS_fchownat:
815: pn(atfd);
816: pn(NULL);
817: pn(NULL);
818: pn(NULL);
819: pn(atflagsname);
820: break;
821: case SYS_fstatat:
822: pn(atfd);
823: pn(NULL);
824: pn(NULL);
825: pn(atflagsname);
826: break;
827: case SYS_linkat:
828: pn(atfd);
829: pn(NULL);
830: pn(atfd);
831: pn(NULL);
832: pn(atflagsname);
833: break;
834: case SYS_mkdirat:
835: case SYS_mkfifoat:
836: case SYS_mknodat:
837: pn(atfd);
838: pn(NULL);
839: pn(modename);
840: break;
841: case SYS_openat: {
842: int flags;
843: int mode;
844:
845: pn(atfd);
846: pn(NULL);
847: if (!fancy)
848: break;
849: flags = ap[0];
850: mode = ap[1];
851: (void)putchar(',');
852: flagsandmodename(flags, mode);
853: ap += 2;
854: narg -= 2;
855: break;
856: }
857: case SYS_readlinkat:
858: pn(atfd);
859: break;
860: case SYS_renameat:
861: pn(atfd);
862: pn(NULL);
863: pn(atfd);
864: break;
865: case SYS_symlinkat:
866: pn(NULL);
867: pn(atfd);
868: break;
869: case SYS_unlinkat:
870: pn(atfd);
871: pn(NULL);
872: pn(atflagsname);
873: break;
874: case SYS_utimensat:
875: pn(atfd);
876: pn(NULL);
877: pn(NULL);
878: pn(atflagsname);
879: break;
1.77 guenther 880: case SYS_pathconf:
881: case SYS_fpathconf:
882: pn(NULL);
883: pn(pathconfname);
884: break;
1.52 otto 885: }
886:
1.54 otto 887: nonnative:
1.52 otto 888: while (narg) {
889: if (sep)
890: putchar(sep);
891: if (decimal)
892: (void)printf("%ld", (long)*ap);
893: else
894: (void)printf("%#lx", (long)*ap);
895: sep = ',';
896: ap++;
897: narg--;
1.1 deraadt 898: }
1.27 mickey 899: (void)printf(")\n");
1.62 otto 900: }
901:
902: static struct ctlname topname[] = CTL_NAMES;
903: static struct ctlname kernname[] = CTL_KERN_NAMES;
904: static struct ctlname vmname[] = CTL_VM_NAMES;
905: static struct ctlname fsname[] = CTL_FS_NAMES;
906: static struct ctlname netname[] = CTL_NET_NAMES;
907: static struct ctlname hwname[] = CTL_HW_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_DDB:
978: SETNAME(ddbname);
979: break;
980: }
981: break;
982: case 2:
983: switch (top[0]) {
984: case CTL_KERN:
985: switch (top[1]) {
986: case KERN_MALLOCSTATS:
987: SETNAME(kernmallocname);
988: break;
989: case KERN_FORKSTAT:
990: SETNAME(forkstatname);
991: break;
992: case KERN_NCHSTATS:
993: SETNAME(nchstatsname);
994: break;
995: case KERN_TTY:
996: SETNAME(ttysname);
997: break;
998: case KERN_SEMINFO:
999: SETNAME(semname);
1000: break;
1001: case KERN_SHMINFO:
1002: SETNAME(shmname);
1003: break;
1004: case KERN_WATCHDOG:
1005: SETNAME(watchdogname);
1006: break;
1.64 guenther 1007: case KERN_PROC:
1008: idx++; /* zero is valid at this level */
1009: SETNAME(kernprocname);
1010: break;
1.62 otto 1011: case KERN_TIMECOUNTER:
1012: SETNAME(tcname);
1013: break;
1014: }
1015: }
1016: break;
1017: }
1018: if (names != NULL && idx > 0 && idx < limit)
1019: return (names[idx].ctl_name);
1020: return (NULL);
1.1 deraadt 1021: }
1022:
1.12 espie 1023: static void
1.17 deraadt 1024: ktrsysret(struct ktr_sysret *ktr)
1.1 deraadt 1025: {
1.50 deraadt 1026: register_t ret = ktr->ktr_retval;
1.12 espie 1027: int error = ktr->ktr_error;
1028: int code = ktr->ktr_code;
1.1 deraadt 1029:
1030: if (code >= current->nsysnames || code < 0)
1031: (void)printf("[%d] ", code);
1.59 otto 1032: else {
1.1 deraadt 1033: (void)printf("%s ", current->sysnames[code]);
1.59 otto 1034: if (ret > 0 && (strcmp(current->sysnames[code], "fork") == 0 ||
1035: strcmp(current->sysnames[code], "vfork") == 0 ||
1.64 guenther 1036: strcmp(current->sysnames[code], "__tfork") == 0 ||
1.59 otto 1037: strcmp(current->sysnames[code], "clone") == 0))
1038: mappidtoemul(ret, current);
1039: }
1.1 deraadt 1040:
1041: if (error == 0) {
1042: if (fancy) {
1.64 guenther 1043: switch (current == &emulations[0] ? code : -1) {
1044: case SYS_sigprocmask:
1.73 guenther 1045: case SYS_sigpending:
1.64 guenther 1046: sigset(ret);
1047: break;
1048: case SYS___thrsigdivert:
1049: signame(ret);
1050: break;
1051: case -1: /* non-default emulation */
1052: default:
1053: (void)printf("%ld", (long)ret);
1054: if (ret < 0 || ret > 9)
1055: (void)printf("/%#lx", (long)ret);
1056: }
1.1 deraadt 1057: } else {
1058: if (decimal)
1.50 deraadt 1059: (void)printf("%ld", (long)ret);
1.1 deraadt 1060: else
1.50 deraadt 1061: (void)printf("%#lx", (long)ret);
1.1 deraadt 1062: }
1063: } else if (error == ERESTART)
1064: (void)printf("RESTART");
1065: else if (error == EJUSTRETURN)
1066: (void)printf("JUSTRETURN");
1067: else {
1068: (void)printf("-1 errno %d", ktr->ktr_error);
1069: if (fancy)
1070: (void)printf(" %s", strerror(ktr->ktr_error));
1071: }
1072: (void)putchar('\n');
1073: }
1074:
1.12 espie 1075: static void
1.37 tedu 1076: ktrnamei(const char *cp, size_t len)
1.1 deraadt 1077: {
1.37 tedu 1078: (void)printf("\"%.*s\"\n", (int)len, cp);
1.1 deraadt 1079: }
1080:
1.12 espie 1081: static void
1.37 tedu 1082: ktremul(char *cp, size_t len)
1.1 deraadt 1083: {
1084: char name[1024];
1085:
1086: if (len >= sizeof(name))
1087: errx(1, "Emulation name too long");
1088:
1089: strncpy(name, cp, len);
1090: name[len] = '\0';
1091: (void)printf("\"%s\"\n", name);
1092:
1093: setemul(name);
1094: }
1095:
1.12 espie 1096: static void
1.37 tedu 1097: ktrgenio(struct ktr_genio *ktr, size_t len)
1.1 deraadt 1098: {
1.37 tedu 1099: unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
1100: int i, j;
1101: size_t datalen = len - sizeof(struct ktr_genio);
1.12 espie 1102: static int screenwidth = 0;
1.31 tedu 1103: int col = 0, width, bpl;
1.32 tedu 1104: unsigned char visbuf[5], *cp, c;
1.1 deraadt 1105:
1106: if (screenwidth == 0) {
1107: struct winsize ws;
1108:
1109: if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
1110: ws.ws_col > 8)
1111: screenwidth = ws.ws_col;
1112: else
1113: screenwidth = 80;
1114: }
1.37 tedu 1115: printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1.1 deraadt 1116: ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
1.58 otto 1117: if (maxdata == 0)
1118: return;
1119: if (datalen > maxdata)
1.1 deraadt 1120: datalen = maxdata;
1.31 tedu 1121: if (iohex && !datalen)
1122: return;
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.17 deraadt 1205: ktrpsig(struct ktr_psig *psig)
1.1 deraadt 1206: {
1207: (void)printf("SIG%s ", sys_signame[psig->signo]);
1208: if (psig->action == SIG_DFL)
1.63 deraadt 1209: (void)printf("SIG_DFL");
1.64 guenther 1210: else {
1211: (void)printf("caught handler=0x%lx mask=",
1212: (u_long)psig->action);
1213: sigset(psig->mask);
1214: }
1.63 deraadt 1215: if (psig->code) {
1216: printf(" code ");
1217: if (fancy) {
1218: switch (psig->signo) {
1219: case SIGILL:
1220: sigill_name(psig->code);
1221: break;
1222: case SIGTRAP:
1223: sigtrap_name(psig->code);
1224: break;
1225: case SIGEMT:
1226: sigemt_name(psig->code);
1227: break;
1228: case SIGFPE:
1229: sigfpe_name(psig->code);
1230: break;
1231: case SIGBUS:
1232: sigbus_name(psig->code);
1233: break;
1234: case SIGSEGV:
1235: sigsegv_name(psig->code);
1236: break;
1237: case SIGCHLD:
1238: sigchld_name(psig->code);
1239: break;
1240: }
1241: }
1242: printf("<%d>", psig->code);
1243: }
1244:
1.14 deraadt 1245: switch (psig->signo) {
1246: case SIGSEGV:
1247: case SIGILL:
1248: case SIGBUS:
1249: case SIGFPE:
1250: printf(" addr=%p trapno=%d", psig->si.si_addr,
1251: psig->si.si_trapno);
1252: break;
1253: default:
1254: break;
1255: }
1256: printf("\n");
1.1 deraadt 1257: }
1258:
1.12 espie 1259: static void
1.17 deraadt 1260: ktrcsw(struct ktr_csw *cs)
1.1 deraadt 1261: {
1262: (void)printf("%s %s\n", cs->out ? "stop" : "resume",
1263: cs->user ? "user" : "kernel");
1264: }
1265:
1.55 otto 1266:
1267:
1.64 guenther 1268: static void
1.55 otto 1269: ktrsockaddr(struct sockaddr *sa)
1270: {
1271: /*
1272: TODO: Support additional address families
1273: #include <netnatm/natm.h>
1274: struct sockaddr_natm *natm;
1275: #include <netsmb/netbios.h>
1276: struct sockaddr_nb *nb;
1277: */
1278: char addr[64];
1279:
1280: /*
1281: * note: ktrstruct() has already verified that sa points to a
1282: * buffer at least sizeof(struct sockaddr) bytes long and exactly
1283: * sa->sa_len bytes long.
1284: */
1285: printf("struct sockaddr { ");
1286: sockfamilyname(sa->sa_family);
1287: printf(", ");
1288:
1289: #define check_sockaddr_len(n) \
1290: if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \
1291: printf("invalid"); \
1292: break; \
1293: }
1294:
1295: switch(sa->sa_family) {
1296: case AF_INET: {
1297: struct sockaddr_in *sa_in;
1298:
1299: sa_in = (struct sockaddr_in *)sa;
1300: check_sockaddr_len(in);
1301: inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr);
1302: printf("%s:%u", addr, ntohs(sa_in->sin_port));
1303: break;
1304: }
1305: case AF_INET6: {
1306: struct sockaddr_in6 *sa_in6;
1307:
1308: sa_in6 = (struct sockaddr_in6 *)sa;
1309: check_sockaddr_len(in6);
1310: inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr);
1311: printf("[%s]:%u", addr, htons(sa_in6->sin6_port));
1312: break;
1313: }
1314: #ifdef IPX
1315: case AF_IPX: {
1316: struct sockaddr_ipx *sa_ipx;
1317:
1318: sa_ipx = (struct sockaddr_ipx *)sa;
1319: check_sockaddr_len(ipx);
1320: /* XXX wish we had ipx_ntop */
1321: printf("%s", ipx_ntoa(sa_ipx->sipx_addr));
1322: break;
1323: }
1324: #endif
1325: case AF_UNIX: {
1326: struct sockaddr_un *sa_un;
1327:
1328: sa_un = (struct sockaddr_un *)sa;
1329: if (sa_un->sun_len <= sizeof(sa_un->sun_len) +
1330: sizeof(sa_un->sun_family)) {
1331: printf("invalid");
1332: break;
1333: }
1334: printf("\"%.*s\"", (int)(sa_un->sun_len -
1335: sizeof(sa_un->sun_len) - sizeof(sa_un->sun_family)),
1336: sa_un->sun_path);
1337: break;
1338: }
1339: default:
1340: printf("unknown address family");
1341: }
1342: printf(" }\n");
1343: }
1344:
1.64 guenther 1345: static void
1346: print_time(time_t t, int relative)
1347: {
1348: char timestr[PATH_MAX + 4];
1349: struct tm *tm;
1350:
1351: if (resolv == 0 || relative)
1352: printf("%jd", (intmax_t)t);
1353: else {
1354: tm = localtime(&t);
1355: (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm);
1356: printf("\"%s\"", timestr);
1357: }
1358: }
1359:
1360: static void
1361: print_timespec(const struct timespec *tsp, int relative)
1.55 otto 1362: {
1.64 guenther 1363: print_time(tsp->tv_sec, relative);
1364: if (tsp->tv_nsec != 0)
1365: printf(".%09ld", tsp->tv_nsec);
1366: }
1367:
1368: static void
1369: ktrstat(const struct stat *statp)
1370: {
1371: char mode[12];
1.55 otto 1372: struct passwd *pwd;
1373: struct group *grp;
1374:
1375: /*
1376: * note: ktrstruct() has already verified that statp points to a
1377: * buffer exactly sizeof(struct stat) bytes long.
1378: */
1.64 guenther 1379: printf("struct stat { ");
1.55 otto 1380: strmode(statp->st_mode, mode);
1381: printf("dev=%d, ino=%u, mode=%s, nlink=%u, ",
1382: statp->st_dev, statp->st_ino, mode, statp->st_nlink);
1383: if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL)
1384: printf("uid=%u, ", statp->st_uid);
1385: else
1386: printf("uid=\"%s\", ", pwd->pw_name);
1387: if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL)
1388: printf("gid=%u, ", statp->st_gid);
1389: else
1390: printf("gid=\"%s\", ", grp->gr_name);
1391: printf("rdev=%d, ", statp->st_rdev);
1392: printf("atime=");
1.64 guenther 1393: print_timespec(&statp->st_atim, 0);
1394: printf(", mtime=");
1395: print_timespec(&statp->st_mtim, 0);
1396: printf(", ctime=");
1397: print_timespec(&statp->st_ctim, 0);
1398: printf(", size=%lld, blocks=%lld, blksize=%u, flags=0x%x, gen=0x%x",
1.55 otto 1399: statp->st_size, statp->st_blocks, statp->st_blksize,
1400: statp->st_flags, statp->st_gen);
1401: printf(" }\n");
1402: }
1403:
1.64 guenther 1404: static void
1.65 guenther 1405: ktrtimespec(const struct timespec *tsp, int relative)
1406: {
1407: printf("struct timespec { ");
1408: print_timespec(tsp, relative);
1409: printf(" }\n");
1410: }
1411:
1412: static void
1413: ktrtimeval(const struct timeval *tvp, int relative)
1414: {
1415: printf("struct timeval { ");
1416: print_time(tvp->tv_sec, relative);
1417: if (tvp->tv_usec != 0)
1418: printf(".%06ld", tvp->tv_usec);
1419: printf(" }\n");
1420: }
1421:
1422: static void
1423: ktrsigaction(const struct sigaction *sa)
1424: {
1425: /*
1426: * note: ktrstruct() has already verified that sa points to a
1427: * buffer exactly sizeof(struct sigaction) bytes long.
1428: */
1429: printf("struct sigaction { ");
1430: if (sa->sa_handler == SIG_DFL)
1431: printf("handler=SIG_DFL");
1432: else if (sa->sa_handler == SIG_IGN)
1433: printf("handler=SIG_IGN");
1434: else if (sa->sa_flags & SA_SIGINFO)
1435: printf("sigaction=%p", (void *)sa->sa_sigaction);
1436: else
1437: printf("handler=%p", (void *)sa->sa_handler);
1438: printf(", mask=");
1439: sigset(sa->sa_mask);
1440: printf(", flags=");
1441: sigactionflagname(sa->sa_flags);
1442: printf(" }\n");
1443: }
1444:
1445: static void
1446: print_rlim(rlim_t lim)
1447: {
1448: if (lim == RLIM_INFINITY)
1449: printf("infinite");
1450: else
1451: printf("%llu", (unsigned long long)lim);
1452: }
1453:
1454: static void
1455: ktrrlimit(const struct rlimit *limp)
1456: {
1457: printf("struct rlimit { ");
1458: printf("cur=");
1459: print_rlim(limp->rlim_cur);
1460: printf(", max=");
1461: print_rlim(limp->rlim_max);
1462: printf(" }\n");
1463: }
1464:
1465: static void
1.72 guenther 1466: ktrtfork(const struct __tfork *tf)
1467: {
1468: printf("struct __tfork { tcb=%p, tid=%p, stack=%p }\n",
1469: tf->tf_tcb, (void *)tf->tf_tid, tf->tf_stack);
1470: }
1471:
1472: static void
1.74 claudio 1473: ktrfdset(const struct fd_set *fds, int len)
1474: {
1475: int nfds, i, start = -1;
1476: char sep = ' ';
1477:
1478: nfds = len * NBBY;
1479: printf("struct fd_set {");
1480: for (i = 0; i <= nfds; i++)
1481: if (i != nfds && FD_ISSET(i, fds)) {
1482: if (start == -1)
1483: start = i;
1484: } else if (start != -1) {
1485: putchar(sep);
1486: if (start == i - 1)
1487: printf("%d", start);
1488: else if (start == i - 2)
1489: printf("%d,%d", start, i - 1);
1490: else
1491: printf("%d-%d", start, i - 1);
1492: sep = ',';
1493: start = -1;
1494: }
1495:
1496: printf(" }\n");
1497: }
1498:
1499: static void
1.55 otto 1500: ktrstruct(char *buf, size_t buflen)
1501: {
1502: char *name, *data;
1503: size_t namelen, datalen;
1504: int i;
1505:
1506: for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0';
1507: ++namelen)
1508: /* nothing */;
1509: if (namelen == buflen)
1510: goto invalid;
1511: if (name[namelen] != '\0')
1512: goto invalid;
1513: data = buf + namelen + 1;
1514: datalen = buflen - namelen - 1;
1515: if (datalen == 0)
1516: goto invalid;
1517: /* sanity check */
1518: for (i = 0; i < namelen; ++i)
1519: if (!isalpha((unsigned char)name[i]))
1520: goto invalid;
1521: if (strcmp(name, "stat") == 0) {
1.64 guenther 1522: struct stat sb;
1523:
1.55 otto 1524: if (datalen != sizeof(struct stat))
1525: goto invalid;
1526: memcpy(&sb, data, datalen);
1527: ktrstat(&sb);
1528: } else if (strcmp(name, "sockaddr") == 0) {
1.64 guenther 1529: struct sockaddr_storage ss;
1530:
1.55 otto 1531: if (datalen > sizeof(ss))
1532: goto invalid;
1533: memcpy(&ss, data, datalen);
1534: if ((ss.ss_family != AF_UNIX &&
1535: datalen < sizeof(struct sockaddr)) || datalen != ss.ss_len)
1536: goto invalid;
1537: ktrsockaddr((struct sockaddr *)&ss);
1.65 guenther 1538: } else if (strcmp(name, "abstimespec") == 0 ||
1539: strcmp(name, "reltimespec") == 0) {
1540: struct timespec ts;
1541:
1542: if (datalen != sizeof(ts))
1543: goto invalid;
1544: memcpy(&ts, data, datalen);
1545: ktrtimespec(&ts, name[0] == 'r');
1546: } else if (strcmp(name, "abstimeval") == 0 ||
1547: strcmp(name, "reltimeval") == 0) {
1548: struct timeval tv;
1549:
1550: if (datalen != sizeof(tv))
1551: goto invalid;
1552: memcpy(&tv, data, datalen);
1553: ktrtimeval(&tv, name[0] == 'r');
1554: } else if (strcmp(name, "sigaction") == 0) {
1555: struct sigaction sa;
1556:
1557: if (datalen != sizeof(sa))
1558: goto invalid;
1559: memcpy(&sa, data, datalen);
1560: ktrsigaction(&sa);
1561: } else if (strcmp(name, "rlimit") == 0) {
1562: struct rlimit lim;
1563:
1564: if (datalen != sizeof(lim))
1565: goto invalid;
1566: memcpy(&lim, data, datalen);
1567: ktrrlimit(&lim);
1.72 guenther 1568: } else if (strcmp(name, "tfork") == 0) {
1569: struct __tfork tf;
1570:
1571: if (datalen != sizeof(tf))
1572: goto invalid;
1573: memcpy(&tf, data, datalen);
1574: ktrtfork(&tf);
1.74 claudio 1575: } else if (strcmp(name, "fdset") == 0) {
1576: struct fd_set *fds;
1577: if ((fds = malloc(datalen)) == NULL)
1578: err(1, "malloc");
1579: memcpy(fds, data, datalen);
1580: ktrfdset(fds, datalen);
1581: free(fds);
1.55 otto 1582: } else {
1.57 otto 1583: printf("unknown structure %s\n", name);
1.55 otto 1584: }
1585: return;
1586: invalid:
1587: printf("invalid record\n");
1588: }
1589:
1.12 espie 1590: static void
1.17 deraadt 1591: usage(void)
1.1 deraadt 1592: {
1593:
1.19 mickey 1594: extern char *__progname;
1595: fprintf(stderr, "usage: %s "
1.68 jmc 1596: "[-dHlnRrTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n"
1.40 sobrado 1597: "%*s[-t [ceinsw]]\n",
1.51 otto 1598: __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
1.1 deraadt 1599: exit(1);
1600: }
1601:
1.12 espie 1602: static void
1.17 deraadt 1603: setemul(const char *name)
1.1 deraadt 1604: {
1605: int i;
1.17 deraadt 1606:
1.1 deraadt 1607: for (i = 0; emulations[i].name != NULL; i++)
1608: if (strcmp(emulations[i].name, name) == 0) {
1609: current = &emulations[i];
1610: return;
1611: }
1612: warnx("Emulation `%s' unknown", name);
1.61 matthew 1613: }
1614:
1615: static void
1616: atfd(int fd)
1617: {
1618: if (fd == AT_FDCWD)
1619: (void)printf("AT_FDCWD");
1620: else if (decimal)
1621: (void)printf("%d", fd);
1622: else
1623: (void)printf("%#x", fd);
1.77 guenther 1624: }
1625:
1626: static void
1627: polltimeout(int timeout)
1628: {
1629: if (timeout == INFTIM)
1630: (void)printf("INFTIM");
1631: else if (decimal)
1632: (void)printf("%d", timeout);
1633: else
1634: (void)printf("%#x", timeout);
1.1 deraadt 1635: }