[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.55

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