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

1.51    ! otto        1: /*     $OpenBSD: kdump.c,v 1.51 2011/06/20 17:51:33 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.1       deraadt    40: #define _KERNEL
                     41: #include <sys/errno.h>
                     42: #undef _KERNEL
                     43:
1.33      tedu       44: #include <ctype.h>
1.1       deraadt    45: #include <err.h>
                     46: #include <signal.h>
                     47: #include <stdio.h>
                     48: #include <stdlib.h>
                     49: #include <string.h>
                     50: #include <unistd.h>
                     51: #include <vis.h>
                     52:
                     53: #include "ktrace.h"
1.22      deraadt    54: #include "kdump.h"
1.51    ! otto       55: #include "kdump_subr.h"
1.12      espie      56: #include "extern.h"
1.1       deraadt    57:
1.31      tedu       58: int timestamp, decimal, iohex, fancy = 1, tail, maxdata;
1.1       deraadt    59: char *tracefile = DEF_TRACEFILE;
                     60: struct ktr_header ktr_header;
1.17      deraadt    61: pid_t pid = -1;
1.1       deraadt    62:
                     63: #define eqs(s1, s2)    (strcmp((s1), (s2)) == 0)
                     64:
                     65: #include <sys/syscall.h>
                     66:
1.25      mickey     67: #include <compat/linux/linux_syscall.h>
                     68: #include <compat/svr4/svr4_syscall.h>
1.1       deraadt    69:
                     70: #define KTRACE
1.19      mickey     71: #define PTRACE
1.7       deraadt    72: #define NFSCLIENT
                     73: #define NFSSERVER
                     74: #define SYSVSEM
                     75: #define SYSVMSG
                     76: #define SYSVSHM
                     77: #define LFS
1.25      mickey     78: #include <kern/syscalls.c>
1.1       deraadt    79:
1.25      mickey     80: #include <compat/linux/linux_syscalls.c>
                     81: #include <compat/svr4/svr4_syscalls.c>
1.1       deraadt    82: #undef KTRACE
1.19      mickey     83: #undef PTRACE
1.7       deraadt    84: #undef NFSCLIENT
                     85: #undef NFSSERVER
                     86: #undef SYSVSEM
                     87: #undef SYSVMSG
                     88: #undef SYSVSHM
                     89: #undef LFS
1.1       deraadt    90:
                     91: struct emulation {
                     92:        char *name;             /* Emulation name */
                     93:        char **sysnames;        /* Array of system call names */
                     94:        int  nsysnames;         /* Number of */
                     95: };
                     96:
                     97: static struct emulation emulations[] = {
1.9       deraadt    98:        { "native",     syscallnames,           SYS_MAXSYSCALL },
                     99:        { "linux",      linux_syscallnames,     LINUX_SYS_MAXSYSCALL },
                    100:        { "svr4",       svr4_syscallnames,      SVR4_SYS_MAXSYSCALL },
1.49      miod      101:        { NULL,         NULL,                   0 }
1.1       deraadt   102: };
                    103:
                    104: struct emulation *current;
                    105:
                    106:
                    107: static char *ptrace_ops[] = {
                    108:        "PT_TRACE_ME",  "PT_READ_I",    "PT_READ_D",    "PT_READ_U",
                    109:        "PT_WRITE_I",   "PT_WRITE_D",   "PT_WRITE_U",   "PT_CONTINUE",
1.15      art       110:        "PT_KILL",      "PT_ATTACH",    "PT_DETACH",    "PT_IO",
1.1       deraadt   111: };
                    112:
1.37      tedu      113: static int fread_tail(void *, size_t, size_t);
1.13      millert   114: static void dumpheader(struct ktr_header *);
                    115: static void ktrcsw(struct ktr_csw *);
1.37      tedu      116: static void ktremul(char *, size_t);
                    117: static void ktrgenio(struct ktr_genio *, size_t);
                    118: static void ktrnamei(const char *, size_t);
1.13      millert   119: static void ktrpsig(struct ktr_psig *);
                    120: static void ktrsyscall(struct ktr_syscall *);
                    121: static void ktrsysret(struct ktr_sysret *);
                    122: static void setemul(const char *);
                    123: static void usage(void);
1.12      espie     124:
1.1       deraadt   125: int
1.17      deraadt   126: main(int argc, char *argv[])
1.1       deraadt   127: {
1.37      tedu      128:        int ch, silent;
                    129:        size_t ktrlen, size;
1.17      deraadt   130:        int trpoints = ALL_POINTS;
1.12      espie     131:        void *m;
1.1       deraadt   132:
1.3       deraadt   133:        current = &emulations[0];       /* native */
1.1       deraadt   134:
1.31      tedu      135:        while ((ch = getopt(argc, argv, "e:f:dlm:nRp:Tt:xX")) != -1)
1.1       deraadt   136:                switch (ch) {
                    137:                case 'e':
                    138:                        setemul(optarg);
                    139:                        break;
                    140:                case 'f':
                    141:                        tracefile = optarg;
                    142:                        break;
                    143:                case 'd':
                    144:                        decimal = 1;
                    145:                        break;
                    146:                case 'l':
                    147:                        tail = 1;
                    148:                        break;
                    149:                case 'm':
                    150:                        maxdata = atoi(optarg);
                    151:                        break;
                    152:                case 'n':
                    153:                        fancy = 0;
                    154:                        break;
1.17      deraadt   155:                case 'p':
                    156:                        pid = atoi(optarg);
                    157:                        break;
1.1       deraadt   158:                case 'R':
                    159:                        timestamp = 2;  /* relative timestamp */
                    160:                        break;
                    161:                case 'T':
                    162:                        timestamp = 1;
                    163:                        break;
                    164:                case 't':
                    165:                        trpoints = getpoints(optarg);
                    166:                        if (trpoints < 0)
                    167:                                errx(1, "unknown trace point in %s", optarg);
                    168:                        break;
1.31      tedu      169:                case 'x':
                    170:                        iohex = 1;
                    171:                        break;
                    172:                case 'X':
                    173:                        iohex = 2;
                    174:                        break;
1.1       deraadt   175:                default:
                    176:                        usage();
                    177:                }
1.5       deraadt   178:        if (argc > optind)
1.1       deraadt   179:                usage();
                    180:
1.37      tedu      181:        m = malloc(size = 1025);
1.1       deraadt   182:        if (m == NULL)
1.37      tedu      183:                err(1, NULL);
1.1       deraadt   184:        if (!freopen(tracefile, "r", stdin))
                    185:                err(1, "%s", tracefile);
                    186:        while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) {
1.17      deraadt   187:                silent = 0;
                    188:                if (pid != -1 && pid != ktr_header.ktr_pid)
                    189:                        silent = 1;
                    190:                if (silent == 0 && trpoints & (1<<ktr_header.ktr_type))
1.1       deraadt   191:                        dumpheader(&ktr_header);
1.37      tedu      192:                ktrlen = ktr_header.ktr_len;
1.1       deraadt   193:                if (ktrlen > size) {
1.23      tedu      194:                        void *newm;
                    195:
                    196:                        newm = realloc(m, ktrlen+1);
                    197:                        if (newm == NULL)
1.37      tedu      198:                                err(1, NULL);
1.23      tedu      199:                        m = newm;
1.1       deraadt   200:                        size = ktrlen;
                    201:                }
                    202:                if (ktrlen && fread_tail(m, ktrlen, 1) == 0)
                    203:                        errx(1, "data too short");
1.17      deraadt   204:                if (silent)
                    205:                        continue;
1.1       deraadt   206:                if ((trpoints & (1<<ktr_header.ktr_type)) == 0)
                    207:                        continue;
                    208:                switch (ktr_header.ktr_type) {
                    209:                case KTR_SYSCALL:
                    210:                        ktrsyscall((struct ktr_syscall *)m);
                    211:                        break;
                    212:                case KTR_SYSRET:
                    213:                        ktrsysret((struct ktr_sysret *)m);
                    214:                        break;
                    215:                case KTR_NAMEI:
                    216:                        ktrnamei(m, ktrlen);
                    217:                        break;
                    218:                case KTR_GENIO:
                    219:                        ktrgenio((struct ktr_genio *)m, ktrlen);
                    220:                        break;
                    221:                case KTR_PSIG:
                    222:                        ktrpsig((struct ktr_psig *)m);
                    223:                        break;
                    224:                case KTR_CSW:
                    225:                        ktrcsw((struct ktr_csw *)m);
                    226:                        break;
                    227:                case KTR_EMUL:
                    228:                        ktremul(m, ktrlen);
                    229:                        break;
                    230:                }
                    231:                if (tail)
                    232:                        (void)fflush(stdout);
                    233:        }
1.12      espie     234:        exit(0);
1.1       deraadt   235: }
                    236:
1.12      espie     237: static int
1.37      tedu      238: fread_tail(void *buf, size_t size, size_t num)
1.1       deraadt   239: {
                    240:        int i;
                    241:
                    242:        while ((i = fread(buf, size, num, stdin)) == 0 && tail) {
                    243:                (void)sleep(1);
                    244:                clearerr(stdin);
                    245:        }
                    246:        return (i);
                    247: }
                    248:
1.12      espie     249: static void
1.17      deraadt   250: dumpheader(struct ktr_header *kth)
1.1       deraadt   251: {
1.17      deraadt   252:        static struct timeval prevtime;
1.1       deraadt   253:        char unknown[64], *type;
                    254:        struct timeval temp;
                    255:
                    256:        switch (kth->ktr_type) {
                    257:        case KTR_SYSCALL:
                    258:                type = "CALL";
                    259:                break;
                    260:        case KTR_SYSRET:
                    261:                type = "RET ";
                    262:                break;
                    263:        case KTR_NAMEI:
                    264:                type = "NAMI";
                    265:                break;
                    266:        case KTR_GENIO:
                    267:                type = "GIO ";
                    268:                break;
                    269:        case KTR_PSIG:
                    270:                type = "PSIG";
                    271:                break;
                    272:        case KTR_CSW:
                    273:                type = "CSW";
                    274:                break;
                    275:        case KTR_EMUL:
                    276:                type = "EMUL";
                    277:                break;
                    278:        default:
1.17      deraadt   279:                (void)snprintf(unknown, sizeof unknown, "UNKNOWN(%d)",
                    280:                    kth->ktr_type);
1.1       deraadt   281:                type = unknown;
                    282:        }
                    283:
1.16      mpech     284:        (void)printf("%6ld %-8.*s ", (long)kth->ktr_pid, MAXCOMLEN,
                    285:            kth->ktr_comm);
1.1       deraadt   286:        if (timestamp) {
                    287:                if (timestamp == 2) {
                    288:                        timersub(&kth->ktr_time, &prevtime, &temp);
                    289:                        prevtime = kth->ktr_time;
                    290:                } else
                    291:                        temp = kth->ktr_time;
                    292:                (void)printf("%ld.%06ld ", temp.tv_sec, temp.tv_usec);
                    293:        }
                    294:        (void)printf("%s  ", type);
                    295: }
                    296:
1.12      espie     297: static void
1.17      deraadt   298: ioctldecode(u_long cmd)
1.2       deraadt   299: {
                    300:        char dirbuf[4], *dir = dirbuf;
                    301:
1.6       deraadt   302:        if (cmd & IOC_IN)
                    303:                *dir++ = 'W';
1.2       deraadt   304:        if (cmd & IOC_OUT)
                    305:                *dir++ = 'R';
                    306:        *dir = '\0';
                    307:
1.33      tedu      308:        printf(decimal ? ",_IO%s('%c',%lu" : ",_IO%s('%c',%#lx",
                    309:            dirbuf, (int)((cmd >> 8) & 0xff), cmd & 0xff);
1.2       deraadt   310:        if ((cmd & IOC_VOID) == 0)
1.34      tedu      311:                printf(decimal ? ",%lu)" : ",%#lx)", (cmd >> 16) & 0xff);
1.2       deraadt   312:        else
                    313:                printf(")");
                    314: }
1.1       deraadt   315:
1.51    ! otto      316: #define print_number(i, n, c) do {                     \
        !           317:        if (c)                                          \
        !           318:                (void)putchar(c);                       \
        !           319:        if (decimal)                                    \
        !           320:                (void)printf("%ld", (long)*i);          \
        !           321:        else                                            \
        !           322:                (void)printf("%#lx", (long)*i);         \
        !           323:        i++;                                            \
        !           324:        n--;                                            \
        !           325:        c = ',';                                        \
        !           326: } while (0);
        !           327:
1.12      espie     328: static void
1.17      deraadt   329: ktrsyscall(struct ktr_syscall *ktr)
1.1       deraadt   330: {
1.51    ! otto      331:        int narg = ktr->ktr_argsize / sizeof(register_t);
1.12      espie     332:        register_t *ap;
1.1       deraadt   333:
                    334:        if (ktr->ktr_code >= current->nsysnames || ktr->ktr_code < 0)
                    335:                (void)printf("[%d]", ktr->ktr_code);
                    336:        else
                    337:                (void)printf("%s", current->sysnames[ktr->ktr_code]);
                    338:        ap = (register_t *)((char *)ktr + sizeof(struct ktr_syscall));
1.27      mickey    339:        (void)putchar('(');
1.51    ! otto      340:        if (narg) {
1.27      mickey    341:                char c = '\0';
1.1       deraadt   342:                if (fancy) {
1.51    ! otto      343:                        switch (ktr->ktr_code) {
        !           344:                        case SYS_ioctl: {
1.12      espie     345:                                const char *cp;
1.17      deraadt   346:
1.1       deraadt   347:                                if (decimal)
1.27      mickey    348:                                        (void)printf("%ld", (long)*ap);
1.1       deraadt   349:                                else
1.27      mickey    350:                                        (void)printf("%#lx", (long)*ap);
1.1       deraadt   351:                                ap++;
1.51    ! otto      352:                                narg--;
1.1       deraadt   353:                                if ((cp = ioctlname(*ap)) != NULL)
                    354:                                        (void)printf(",%s", cp);
1.2       deraadt   355:                                else
                    356:                                        ioctldecode(*ap);
1.1       deraadt   357:                                c = ',';
                    358:                                ap++;
1.51    ! otto      359:                                narg--;
        !           360:                                break;
        !           361:                        }
        !           362:                        case SYS___sysctl: {
1.27      mickey    363:                                int *np, n;
                    364:
                    365:                                n = ap[1];
1.28      deraadt   366:                                if (n > CTL_MAXNAME)
                    367:                                        n = CTL_MAXNAME;
1.27      mickey    368:                                np = (int *)(ap + 6);
                    369:                                for (; n--; np++) {
                    370:                                        if (c)
                    371:                                                putchar(c);
                    372:                                        printf("%d", *np);
                    373:                                        c = '.';
                    374:                                }
                    375:
                    376:                                c = ',';
                    377:                                ap += 2;
1.51    ! otto      378:                                narg -= 2;
        !           379:                                break;
        !           380:                        }
        !           381:                        case SYS_ptrace:
1.24      miod      382:                                if (*ap >= 0 && *ap <
1.1       deraadt   383:                                    sizeof(ptrace_ops) / sizeof(ptrace_ops[0]))
1.27      mickey    384:                                        (void)printf("%s", ptrace_ops[*ap]);
1.24      miod      385:                                else switch(*ap) {
                    386: #ifdef PT_GETFPREGS
                    387:                                case PT_GETFPREGS:
1.27      mickey    388:                                        (void)printf("PT_GETFPREGS");
1.24      miod      389:                                        break;
                    390: #endif
                    391:                                case PT_GETREGS:
1.27      mickey    392:                                        (void)printf("PT_GETREGS");
1.24      miod      393:                                        break;
                    394: #ifdef PT_SETFPREGS
                    395:                                case PT_SETFPREGS:
1.27      mickey    396:                                        (void)printf("PT_SETFPREGS");
1.24      miod      397:                                        break;
                    398: #endif
                    399:                                case PT_SETREGS:
1.27      mickey    400:                                        (void)printf("PT_SETREGS");
1.24      miod      401:                                        break;
                    402: #ifdef PT_STEP
                    403:                                case PT_STEP:
1.27      mickey    404:                                        (void)printf("PT_STEP");
1.24      miod      405:                                        break;
                    406: #endif
                    407: #ifdef PT_WCOOKIE
                    408:                                case PT_WCOOKIE:
1.27      mickey    409:                                        (void)printf("PT_WCOOKIE");
1.24      miod      410:                                        break;
                    411: #endif
                    412:                                default:
1.27      mickey    413:                                        (void)printf("%ld", (long)*ap);
1.24      miod      414:                                        break;
                    415:                                }
1.1       deraadt   416:                                c = ',';
                    417:                                ap++;
1.51    ! otto      418:                                narg--;
        !           419:                                break;
        !           420:                        case SYS_access:
        !           421:                                print_number(ap, narg, c);
        !           422:                                (void)putchar(',');
        !           423:                                accessmodename((int)*ap);
        !           424:                                ap++;
        !           425:                                narg--;
        !           426:                                break;
        !           427:                        case SYS_chmod:
        !           428:                        case SYS_fchmod:
        !           429:                                print_number(ap, narg, c);
        !           430:                                (void)putchar(',');
        !           431:                                modename((int)*ap);
        !           432:                                ap++;
        !           433:                                narg--;
        !           434:                                break;
        !           435:                        case SYS_fcntl: {
        !           436:                                int cmd;
        !           437:                                int arg;
        !           438:                                print_number(ap, narg, c);
        !           439:                                cmd = *ap;
        !           440:                                arg = *++ap;
        !           441:                                (void)putchar(',');
        !           442:                                fcntlcmdname(cmd, arg, decimal);
        !           443:                                ap++;
        !           444:                                narg -= 2;
        !           445:                                break;
        !           446:                        }
        !           447:                        case SYS_flock:
        !           448:                                print_number(ap, narg, c);
        !           449:                                (void)putchar(',');
        !           450:                                flockname((int)*ap);
        !           451:                                ap++;
        !           452:                                narg--;
        !           453:                                break;
        !           454:                        case SYS_getrlimit:
        !           455:                        case SYS_setrlimit:
        !           456:                                rlimitname((int)*ap);
        !           457:                                ap++;
        !           458:                                narg--;
        !           459:                                c = ',';
        !           460:                                break;
        !           461:                        case SYS_getsockopt:
        !           462:                        case SYS_setsockopt:
        !           463:                                print_number(ap, narg, c);
        !           464:                                (void)putchar(',');
        !           465:                                sockoptlevelname((int)*ap, decimal);
        !           466:                                if ((int)*ap == SOL_SOCKET) {
        !           467:                                        ap++;
        !           468:                                        narg--;
        !           469:                                        (void)putchar(',');
        !           470:                                        sockoptname((int)*ap);
        !           471:                                }
        !           472:                                ap++;
        !           473:                                narg--;
        !           474:                                break;
        !           475:                        case SYS_kill:
        !           476:                                print_number(ap, narg, c);
        !           477:                                (void)putchar(',');
        !           478:                                signame((int)*ap);
        !           479:                                ap++;
        !           480:                                narg--;
        !           481:                                break;
        !           482:                        case SYS_lseek:
        !           483:                                print_number(ap, narg, c);
        !           484:                                /* skip padding */
        !           485:                                ap++;
        !           486:                                narg--;
        !           487:                                print_number(ap, narg, c);
        !           488:                                (void)putchar(',');
        !           489:                                whencename((int)*ap);
        !           490:                                ap++;
        !           491:                                narg--;
        !           492:                                break;
        !           493:                        case SYS_madvise:
        !           494:                                print_number(ap, narg, c);
        !           495:                                print_number(ap, narg, c);
        !           496:                                (void)putchar(',');
        !           497:                                madvisebehavname((int)*ap);
        !           498:                                ap++;
        !           499:                                narg--;
        !           500:                                break;
        !           501:                        case SYS_minherit:
        !           502:                                print_number(ap, narg, c);
        !           503:                                print_number(ap, narg, c);
        !           504:                                (void)putchar(',');
        !           505:                                minheritname((int)*ap);
        !           506:                                ap++;
        !           507:                                narg--;
        !           508:                                break;
        !           509:                        case SYS_mlockall:
        !           510:                                mlockallname((int)*ap);
        !           511:                                ap++;
        !           512:                                narg--;
        !           513:                                break;
        !           514:                        case SYS_mmap:
        !           515:                                print_number(ap, narg, c);
        !           516:                                print_number(ap, narg, c);
        !           517:                                (void)putchar(',');
        !           518:                                mmapprotname((int)*ap);
        !           519:                                (void)putchar(',');
        !           520:                                ap++;
        !           521:                                narg--;
        !           522:                                mmapflagsname((int)*ap);
        !           523:                                ap++;
        !           524:                                narg--;
        !           525:                                print_number(ap, narg, c);
        !           526:                                /* skip padding */
        !           527:                                ap++;
        !           528:                                narg--;
        !           529:                                break;
        !           530:                        case SYS_mprotect:
        !           531:                                print_number(ap, narg, c);
        !           532:                                print_number(ap, narg, c);
        !           533:                                (void)putchar(',');
        !           534:                                mmapprotname((int)*ap);
        !           535:                                ap++;
        !           536:                                narg--;
        !           537:                                break;
        !           538:                        case SYS_mquery:
        !           539:                                print_number(ap, narg, c);
        !           540:                                print_number(ap, narg, c);
        !           541:                                (void)putchar(',');
        !           542:                                mmapprotname((int)*ap);
        !           543:                                ap++;
        !           544:                                narg--;
        !           545:                                (void)putchar(',');
        !           546:                                mmapflagsname((int)*ap);
        !           547:                                ap++;
        !           548:                                narg--;
        !           549:                                print_number(ap, narg, c);
        !           550:                                /* skip padding */
        !           551:                                ap++;
        !           552:                                narg--;
        !           553:                                break;
        !           554:                        case SYS_msync:
        !           555:                                print_number(ap, narg, c);
        !           556:                                print_number(ap, narg, c);
        !           557:                                (void)putchar(',');
        !           558:                                msyncflagsname((int)*ap);
        !           559:                                ap++;
        !           560:                                narg--;
        !           561:                                break;
        !           562:                        case SYS_msgctl:
        !           563:                                print_number(ap, narg, c);
        !           564:                                (void)putchar(',');
        !           565:                                shmctlname((int)*ap);
        !           566:                                ap++;
        !           567:                                narg--;
        !           568:                                break;
        !           569:                        case SYS_open: {
        !           570:                                int     flags;
        !           571:                                int     mode;
        !           572:                                print_number(ap, narg, c);
        !           573:                                flags = *ap;
        !           574:                                mode = *++ap;
        !           575:                                (void)putchar(',');
        !           576:                                flagsandmodename(flags, mode, decimal);
        !           577:                                ap++;
        !           578:                                narg -= 2;
        !           579:                                break;
        !           580:                        }
        !           581:                        case SYS_pread:
        !           582:                        case SYS_preadv:
        !           583:                        case SYS_pwrite:
        !           584:                        case SYS_pwritev:
        !           585:                                print_number(ap, narg, c);
        !           586:                                print_number(ap, narg, c);
        !           587:                                print_number(ap, narg, c);
        !           588:                                /* skip padding */
        !           589:                                ap++;
        !           590:                                narg--;
        !           591:                                break;
        !           592:                        case SYS_recvmsg:
        !           593:                        case SYS_sendmsg:
        !           594:                                print_number(ap, narg, c);
        !           595:                                print_number(ap, narg, c);
        !           596:                                (void)putchar(',');
        !           597:                                sendrecvflagsname((int)*ap);
        !           598:                                ap++;
        !           599:                                narg--;
        !           600:                                break;
        !           601:                        case SYS_recvfrom:
        !           602:                        case SYS_sendto:
        !           603:                                print_number(ap, narg, c);
        !           604:                                print_number(ap, narg, c);
        !           605:                                print_number(ap, narg, c);
        !           606:                                (void)putchar(',');
        !           607:                                sendrecvflagsname((int)*ap);
        !           608:                                ap++;
        !           609:                                narg--;
        !           610:                                break;
        !           611:                        case SYS___semctl:
        !           612:                                print_number(ap, narg, c);
        !           613:                                print_number(ap, narg, c);
        !           614:                                (void)putchar(',');
        !           615:                                semctlname((int)*ap);
        !           616:                                ap++;
        !           617:                                narg--;
        !           618:                                break;
        !           619:                        case SYS_semget:
        !           620:                                print_number(ap, narg, c);
        !           621:                                print_number(ap, narg, c);
        !           622:                                (void)putchar(',');
        !           623:                                semgetname((int)*ap);
        !           624:                                ap++;
        !           625:                                narg--;
        !           626:                                break;
        !           627:                        case SYS_shmat:
        !           628:                                print_number(ap, narg, c);
        !           629:                                print_number(ap, narg, c);
        !           630:                                (void)putchar(',');
        !           631:                                shmatname((int)*ap);
        !           632:                                ap++;
        !           633:                                narg--;
        !           634:                                break;
        !           635:                        case SYS_shmctl:
        !           636:                                print_number(ap, narg, c);
        !           637:                                (void)putchar(',');
        !           638:                                shmctlname((int)*ap);
        !           639:                                ap++;
        !           640:                                narg--;
        !           641:                                break;
        !           642:                        case SYS_sigaction:
        !           643:                                signame((int)*ap);
        !           644:                                ap++;
        !           645:                                narg--;
        !           646:                                c = ',';
        !           647:                                break;
        !           648:                        case SYS_sigprocmask:
        !           649:                                sigprocmaskhowname((int)*ap);
        !           650:                                ap++;
        !           651:                                narg--;
        !           652:                                c = ',';
        !           653:                                break;
        !           654:                        case SYS_socket: {
        !           655:                                int sockdomain = (int)*ap;
        !           656:                                sockdomainname(sockdomain);
        !           657:                                ap++;
        !           658:                                narg--;
        !           659:                                (void)putchar(',');
        !           660:                                socktypename((int)*ap);
        !           661:                                ap++;
        !           662:                                narg--;
        !           663:                                if (sockdomain == PF_INET ||
        !           664:                                    sockdomain == PF_INET6) {
        !           665:                                        (void)putchar(',');
        !           666:                                        sockipprotoname((int)*ap);
        !           667:                                        ap++;
        !           668:                                        narg--;
        !           669:                                }
        !           670:                                c = ',';
        !           671:                                break;
        !           672:                        }
        !           673:                        case SYS_socketpair:
        !           674:                                sockdomainname((int)*ap);
        !           675:                                ap++;
        !           676:                                narg--;
        !           677:                                (void)putchar(',');
        !           678:                                socktypename((int)*ap);
        !           679:                                ap++;
        !           680:                                narg--;
        !           681:                                c = ',';
        !           682:                                break;
        !           683:                        case SYS_truncate:
        !           684:                        case SYS_ftruncate:
        !           685:                                print_number(ap, narg, c);
        !           686:                                /* skip padding */
        !           687:                                ap++;
        !           688:                                narg--;
        !           689:                                break;
        !           690:                        case SYS_wait4:
        !           691:                                print_number(ap, narg, c);
        !           692:                                print_number(ap, narg, c);
        !           693:                                (void)putchar(',');
        !           694:                                wait4optname((int)*ap);
        !           695:                                ap++;
        !           696:                                narg--;
        !           697:                                break;
1.1       deraadt   698:                        }
                    699:                }
1.51    ! otto      700:                while (narg) {
1.27      mickey    701:                        if (c)
                    702:                                putchar(c);
1.1       deraadt   703:                        if (decimal)
1.27      mickey    704:                                (void)printf("%ld", (long)*ap);
1.1       deraadt   705:                        else
1.27      mickey    706:                                (void)printf("%#lx", (long)*ap);
1.1       deraadt   707:                        c = ',';
                    708:                        ap++;
1.51    ! otto      709:                        narg--;
1.1       deraadt   710:                }
                    711:        }
1.27      mickey    712:        (void)printf(")\n");
1.1       deraadt   713: }
                    714:
1.12      espie     715: static void
1.17      deraadt   716: ktrsysret(struct ktr_sysret *ktr)
1.1       deraadt   717: {
1.50      deraadt   718:        register_t ret = ktr->ktr_retval;
1.12      espie     719:        int error = ktr->ktr_error;
                    720:        int code = ktr->ktr_code;
1.1       deraadt   721:
                    722:        if (code >= current->nsysnames || code < 0)
                    723:                (void)printf("[%d] ", code);
                    724:        else
                    725:                (void)printf("%s ", current->sysnames[code]);
                    726:
                    727:        if (error == 0) {
                    728:                if (fancy) {
1.50      deraadt   729:                        (void)printf("%ld", (long)ret);
1.1       deraadt   730:                        if (ret < 0 || ret > 9)
1.50      deraadt   731:                                (void)printf("/%#lx", (long)ret);
1.1       deraadt   732:                } else {
                    733:                        if (decimal)
1.50      deraadt   734:                                (void)printf("%ld", (long)ret);
1.1       deraadt   735:                        else
1.50      deraadt   736:                                (void)printf("%#lx", (long)ret);
1.1       deraadt   737:                }
                    738:        } else if (error == ERESTART)
                    739:                (void)printf("RESTART");
                    740:        else if (error == EJUSTRETURN)
                    741:                (void)printf("JUSTRETURN");
                    742:        else {
                    743:                (void)printf("-1 errno %d", ktr->ktr_error);
                    744:                if (fancy)
                    745:                        (void)printf(" %s", strerror(ktr->ktr_error));
                    746:        }
                    747:        (void)putchar('\n');
                    748: }
                    749:
1.12      espie     750: static void
1.37      tedu      751: ktrnamei(const char *cp, size_t len)
1.1       deraadt   752: {
1.37      tedu      753:        (void)printf("\"%.*s\"\n", (int)len, cp);
1.1       deraadt   754: }
                    755:
1.12      espie     756: static void
1.37      tedu      757: ktremul(char *cp, size_t len)
1.1       deraadt   758: {
                    759:        char name[1024];
                    760:
                    761:        if (len >= sizeof(name))
                    762:                errx(1, "Emulation name too long");
                    763:
                    764:        strncpy(name, cp, len);
                    765:        name[len] = '\0';
                    766:        (void)printf("\"%s\"\n", name);
                    767:
                    768:        setemul(name);
                    769: }
                    770:
1.12      espie     771: static void
1.37      tedu      772: ktrgenio(struct ktr_genio *ktr, size_t len)
1.1       deraadt   773: {
1.37      tedu      774:        unsigned char *dp = (unsigned char *)ktr + sizeof(struct ktr_genio);
                    775:        int i, j;
                    776:        size_t datalen = len - sizeof(struct ktr_genio);
1.12      espie     777:        static int screenwidth = 0;
1.31      tedu      778:        int col = 0, width, bpl;
1.32      tedu      779:        unsigned char visbuf[5], *cp, c;
1.1       deraadt   780:
                    781:        if (screenwidth == 0) {
                    782:                struct winsize ws;
                    783:
                    784:                if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 &&
                    785:                    ws.ws_col > 8)
                    786:                        screenwidth = ws.ws_col;
                    787:                else
                    788:                        screenwidth = 80;
                    789:        }
1.37      tedu      790:        printf("fd %d %s %zu bytes\n", ktr->ktr_fd,
1.1       deraadt   791:                ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen);
                    792:        if (maxdata && datalen > maxdata)
                    793:                datalen = maxdata;
1.31      tedu      794:        if (iohex && !datalen)
                    795:                return;
                    796:        if (iohex == 1) {
                    797:                putchar('\t');
                    798:                col = 8;
                    799:                for (i = 0; i < datalen; i++) {
1.35      tedu      800:                        printf("%02x", dp[i]);
1.31      tedu      801:                        col += 3;
                    802:                        if (i < datalen - 1) {
                    803:                                if (col + 3 > screenwidth) {
                    804:                                        printf("\n\t");
                    805:                                        col = 8;
                    806:                                } else
                    807:                                        putchar(' ');
                    808:                        }
                    809:                }
                    810:                putchar('\n');
                    811:                return;
                    812:        }
                    813:        if (iohex == 2) {
                    814:                bpl = (screenwidth - 13)/4;
                    815:                if (bpl <= 0)
                    816:                        bpl = 1;
                    817:                for (i = 0; i < datalen; i += bpl) {
                    818:                        printf("   %04x:  ", i);
                    819:                        for (j = 0; j < bpl; j++) {
                    820:                                if (i+j >= datalen)
                    821:                                        printf("   ");
                    822:                                else
1.35      tedu      823:                                        printf("%02x ", dp[i+j]);
1.31      tedu      824:                        }
                    825:                        putchar(' ');
                    826:                        for (j = 0; j < bpl; j++) {
                    827:                                if (i+j >= datalen)
                    828:                                        break;
                    829:                                c = dp[i+j];
                    830:                                if (!isprint(c))
                    831:                                        c = '.';
                    832:                                putchar(c);
                    833:                        }
                    834:                        putchar('\n');
                    835:                }
                    836:                return;
                    837:        }
1.1       deraadt   838:        (void)printf("       \"");
                    839:        col = 8;
                    840:        for (; datalen > 0; datalen--, dp++) {
1.31      tedu      841:                (void)vis(visbuf, *dp, VIS_CSTYLE, *(dp+1));
1.1       deraadt   842:                cp = visbuf;
1.17      deraadt   843:
1.1       deraadt   844:                /*
                    845:                 * Keep track of printables and
                    846:                 * space chars (like fold(1)).
                    847:                 */
                    848:                if (col == 0) {
                    849:                        (void)putchar('\t');
                    850:                        col = 8;
                    851:                }
1.17      deraadt   852:                switch (*cp) {
1.1       deraadt   853:                case '\n':
                    854:                        col = 0;
                    855:                        (void)putchar('\n');
                    856:                        continue;
                    857:                case '\t':
                    858:                        width = 8 - (col&07);
                    859:                        break;
                    860:                default:
                    861:                        width = strlen(cp);
                    862:                }
                    863:                if (col + width > (screenwidth-2)) {
                    864:                        (void)printf("\\\n\t");
                    865:                        col = 8;
                    866:                }
                    867:                col += width;
                    868:                do {
                    869:                        (void)putchar(*cp++);
                    870:                } while (*cp);
                    871:        }
                    872:        if (col == 0)
                    873:                (void)printf("       ");
                    874:        (void)printf("\"\n");
                    875: }
                    876:
1.12      espie     877: static void
1.17      deraadt   878: ktrpsig(struct ktr_psig *psig)
1.1       deraadt   879: {
                    880:        (void)printf("SIG%s ", sys_signame[psig->signo]);
                    881:        if (psig->action == SIG_DFL)
1.14      deraadt   882:                (void)printf("SIG_DFL code %d", psig->code);
1.1       deraadt   883:        else
1.14      deraadt   884:                (void)printf("caught handler=0x%lx mask=0x%x",
                    885:                    (u_long)psig->action, psig->mask);
                    886:        switch (psig->signo) {
                    887:        case SIGSEGV:
                    888:        case SIGILL:
                    889:        case SIGBUS:
                    890:        case SIGFPE:
                    891:                printf(" addr=%p trapno=%d", psig->si.si_addr,
                    892:                    psig->si.si_trapno);
                    893:                break;
                    894:        default:
                    895:                break;
                    896:        }
                    897:        printf("\n");
1.1       deraadt   898: }
                    899:
1.12      espie     900: static void
1.17      deraadt   901: ktrcsw(struct ktr_csw *cs)
1.1       deraadt   902: {
                    903:        (void)printf("%s %s\n", cs->out ? "stop" : "resume",
                    904:            cs->user ? "user" : "kernel");
                    905: }
                    906:
1.12      espie     907: static void
1.17      deraadt   908: usage(void)
1.1       deraadt   909: {
                    910:
1.19      mickey    911:        extern char *__progname;
                    912:        fprintf(stderr, "usage: %s "
1.40      sobrado   913:            "[-dlnRTXx] [-e emulation] [-f file] [-m maxdata] [-p pid]\n"
                    914:            "%*s[-t [ceinsw]]\n",
1.51    ! otto      915:            __progname, (int)(sizeof("usage: ") + strlen(__progname)), "");
1.1       deraadt   916:        exit(1);
                    917: }
                    918:
1.12      espie     919: static void
1.17      deraadt   920: setemul(const char *name)
1.1       deraadt   921: {
                    922:        int i;
1.17      deraadt   923:
1.1       deraadt   924:        for (i = 0; emulations[i].name != NULL; i++)
                    925:                if (strcmp(emulations[i].name, name) == 0) {
                    926:                        current = &emulations[i];
                    927:                        return;
                    928:                }
                    929:        warnx("Emulation `%s' unknown", name);
                    930: }