[BACK]Return to kdump.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / kdump

Annotation of src/usr.bin/kdump/kdump.c, Revision 1.59

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