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

Annotation of src/usr.bin/pctr/pctr.c, Revision 1.18

1.18    ! mikeb       1: /*     $OpenBSD: pctr.c,v 1.17 2007/10/25 16:38:06 mikeb Exp $ */
1.13      deraadt     2:
                      3: /*
                      4:  * Copyright (c) 2007 Mike Belopuhov, Aleksey Lomovtsev
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
1.1       dm         18:
                     19: /*
                     20:  * Pentium performance counter control program for OpenBSD.
                     21:  * Copyright 1996 David Mazieres <dm@lcs.mit.edu>.
                     22:  *
                     23:  * Modification and redistribution in source and binary forms is
                     24:  * permitted provided that due credit is given to the author and the
1.5       pvalchev   25:  * OpenBSD project by leaving this copyright notice intact.
1.1       dm         26:  */
                     27:
1.4       downsj     28: #include <sys/param.h>
1.1       dm         29: #include <sys/types.h>
                     30: #include <sys/stat.h>
1.4       downsj     31: #include <sys/sysctl.h>
1.1       dm         32: #include <sys/ioctl.h>
1.13      deraadt    33:
1.1       dm         34: #include <machine/cpu.h>
                     35: #include <machine/pctr.h>
1.4       downsj     36: #include <machine/specialreg.h>
1.1       dm         37:
1.13      deraadt    38: #include <errno.h>
                     39: #include <err.h>
                     40: #include <fcntl.h>
                     41: #include <stdio.h>
                     42: #include <stdlib.h>
                     43: #include <string.h>
                     44: #include <unistd.h>
                     45:
                     46: #include "pctrvar.h"
                     47:
                     48: static int      cpu_type;
                     49: static int      tsc_avail;
                     50:
                     51: static int      ctr, func, masku, thold;
                     52: static int      cflag, eflag, iflag, kflag, uflag;
                     53: static int      Mflag, Eflag, Sflag, Iflag, Aflag;
                     54:
1.18    ! mikeb      55: static void     pctr_cpu_creds(void);
1.13      deraadt    56: static char    *pctr_fn2str(u_int32_t);
                     57: static void     pctr_printvals(struct pctrst *);
                     58: static int      pctr_read(struct pctrst *);
                     59: static int      pctr_write(int, u_int32_t);
                     60: static void     pctr_list_fnct(void);
                     61: static int      pctr_set_cntr(void);
                     62: static void     usage(void);
                     63:
                     64: int
                     65: main(int argc, char **argv)
                     66: {
                     67:        const char *errstr;
                     68:        struct pctrst st;
                     69:        int ch = -1;
                     70:        int list_mode = 0, set_mode = 0;
                     71:
1.18    ! mikeb      72:        pctr_cpu_creds();
1.13      deraadt    73:
1.18    ! mikeb      74:        while ((ch = getopt(argc, argv, "AcEef:IiklMm:Ss:t:u")) != -1)
1.13      deraadt    75:                switch (ch) {
1.17      mikeb      76:                case 'A':
                     77:                        Aflag++;
                     78:                        break;
                     79:                case 'c':
                     80:                        cflag++;
1.13      deraadt    81:                        break;
1.17      mikeb      82:                case 'E':
1.18    ! mikeb      83:                        Eflag++;
        !            84:                        break;
1.17      mikeb      85:                case 'e':
                     86:                        eflag++;
1.13      deraadt    87:                        break;
                     88:                case 'f':
                     89:                        if (sscanf(optarg, "%x", &func) <= 0 || func < 0 ||
                     90:                            func > PCTR_MAX_FUNCT)
                     91:                                errx(1, "invalid function number");
                     92:                        break;
1.18    ! mikeb      93:                case 'I':
        !            94:                        Iflag++;
        !            95:                        break;
1.17      mikeb      96:                case 'i':
                     97:                        iflag++;
                     98:                        break;
                     99:                case 'k':
                    100:                        kflag++;
                    101:                        break;
                    102:                case 'l':
                    103:                        list_mode++;
                    104:                        break;
1.18    ! mikeb     105:                case 'M':
        !           106:                        Mflag++;
        !           107:                        break;
1.13      deraadt   108:                case 'm':
                    109:                        if (sscanf(optarg, "%x", &masku) <= 0 || masku < 0 ||
                    110:                            masku > PCTR_MAX_UMASK)
                    111:                                errx(1, "invalid unit mask number");
                    112:                        break;
1.18    ! mikeb     113:                case 'S':
        !           114:                        Sflag++;
        !           115:                        break;
1.17      mikeb     116:                case 's':
                    117:                        set_mode++;
                    118:                        ctr = strtonum(optarg, 0, PCTR_NUM-1, &errstr);
                    119:                        if (errstr)
                    120:                                errx(1, "counter number is %s: %s", errstr,
                    121:                                    optarg);
                    122:                        break;
1.13      deraadt   123:                case 't':
                    124:                        thold = strtonum(optarg, 0, 0xff, &errstr);
                    125:                        if (errstr)
                    126:                                errx(1, "threshold is %s: %s", errstr, optarg);
                    127:                        break;
                    128:                case 'u':
                    129:                        uflag++;
                    130:                        break;
                    131:                default:
                    132:                        usage();
                    133:                        /* NOTREACHED */
                    134:                }
                    135:        argc -= optind;
                    136:        argv += optind;
                    137:
1.18    ! mikeb     138:        if (argc)
        !           139:                usage();
        !           140:
        !           141:        if (Aflag && (Mflag || Eflag || Sflag || Iflag))
        !           142:                usage();
        !           143:
1.13      deraadt   144:        if (list_mode)
                    145:                pctr_list_fnct();
                    146:        else if (set_mode) {
                    147:                if (pctr_set_cntr() < 0)
                    148:                        err(1, "pctr_set_cntr");
                    149:        } else {
                    150:                bzero(&st, sizeof(st));
                    151:                if (pctr_read(&st) < 0)
                    152:                        err(1, "pctr_read");
                    153:                pctr_printvals(&st);
                    154:        }
                    155:        return (0);
                    156: }
                    157:
1.18    ! mikeb     158: static void
1.13      deraadt   159: pctr_cpu_creds(void)
                    160: {
                    161:        int atype;
                    162:        char arch[16], vendor[64];
                    163:        int mib[2], cpu_id, cpu_feature;
                    164:        size_t len;
                    165:
                    166:        /* Get the architecture */
                    167:        mib[0] = CTL_HW;
                    168:        mib[1] = HW_MACHINE;
                    169:        len = sizeof(arch) - 1;
                    170:        bzero(arch, sizeof(arch));
                    171:        if (sysctl(mib, 2, arch, &len, NULL, 0) == -1)
                    172:                err(1, "HW_MACHINE");
                    173:        arch[len] = '\0';
                    174:
                    175:        if (strcmp(arch, "i386") == 0)
                    176:                atype = ARCH_I386;
                    177:        else if (strcmp(arch, "amd64") == 0)
                    178:                atype = ARCH_AMD64;
                    179:        else
1.18    ! mikeb     180:                errx(1, "architecture %s is not supported", arch);
1.13      deraadt   181:
                    182:        /* Get the CPU id */
                    183:        mib[0] = CTL_MACHDEP;
                    184:        mib[1] = CPU_CPUID;
                    185:        len = sizeof(cpu_id);
                    186:        if (sysctl(mib, 2, &cpu_id, &len, NULL, 0) == -1)
                    187:                err(1, "CPU_CPUID");
                    188:
                    189:        /* Get the CPU features */
                    190:        mib[1] = CPU_CPUFEATURE;
                    191:        len = sizeof(cpu_feature);
                    192:        if (sysctl(mib, 2, &cpu_feature, &len, NULL, 0) == -1)
                    193:                err(1, "CPU_CPUFEATURE");
                    194:
                    195:        /* Get the processor vendor */
                    196:        mib[0] = CTL_MACHDEP;
                    197:        mib[1] = CPU_CPUVENDOR;
                    198:        len = sizeof(vendor) - 1;
                    199:        bzero(vendor, sizeof(vendor));
                    200:        if (sysctl(mib, 2, vendor, &len, NULL, 0) == -1)
                    201:                err(1, "CPU_CPUVENDOR");
                    202:        vendor[len] = '\0';
                    203:
                    204:        switch (atype) {
                    205:        case ARCH_I386:
                    206:                if (strcmp(vendor, "AuthenticAMD") == 0) {
                    207:                        if (((cpu_id >> 8) & 15) >= 6)
                    208:                                cpu_type = CPU_AMD;
                    209:                        else
                    210:                                cpu_type = CPU_UNDEF;   /* old AMD cpu */
                    211:
                    212:                } else if (strcmp(vendor, "GenuineIntel") == 0) {
                    213:                        if (((cpu_id >> 8) & 15) == 6 &&
                    214:                            ((cpu_id >> 4) & 15) > 14)
                    215:                                cpu_type = CPU_CORE;
                    216:                        else if (((cpu_id >> 8) & 15) >= 6)
                    217:                                cpu_type = CPU_P6;
                    218:                        else if (((cpu_id >> 4) & 15) > 0)
                    219:                                cpu_type = CPU_P5;
                    220:                        else
                    221:                                cpu_type = CPU_UNDEF;   /* old Intel cpu */
                    222:                }
                    223:                if (cpu_feature & CPUID_TSC)
                    224:                        tsc_avail = 1;
                    225:                break;
                    226:        case ARCH_AMD64:
                    227:                if (strcmp(vendor, "AuthenticAMD") == 0)
                    228:                        cpu_type = CPU_AMD;
                    229:                else if (strcmp(vendor, "GenuineIntel") == 0)
                    230:                        cpu_type = CPU_CORE;
                    231:                if (cpu_feature & CPUID_TSC)
                    232:                        tsc_avail = 1;
                    233:                break;
                    234:        }
                    235: }
                    236:
                    237: static __inline int
                    238: pctr_ctrfn_index(struct ctrfn *cfnp, u_int32_t func)
                    239: {
                    240:        int i;
                    241:
                    242:        for (i = 0; cfnp[i].name != NULL; i++)
                    243:                if (cfnp[i].fn == func)
                    244:                        return (i);
                    245:        return (-1);
                    246: }
                    247:
                    248: static char *
                    249: pctr_fn2str(u_int32_t sel)
                    250: {
                    251:        static char buf[128];
                    252:        struct ctrfn *cfnp = NULL;
                    253:        char th[6], um[5], *msg;
                    254:        u_int32_t fn;
                    255:        int ind;
                    256:
                    257:        bzero(buf, sizeof(buf));
                    258:        bzero(th, sizeof(th));
                    259:        bzero(um, sizeof(um));
                    260:        switch (cpu_type) {
                    261:        case CPU_P5:
                    262:                fn = sel & 0x3f;
                    263:                if ((ind = pctr_ctrfn_index(p5fn, fn)) < 0)
                    264:                        msg = "unknown function";
                    265:                else
                    266:                        msg = p5fn[ind].name;
                    267:                snprintf(buf, sizeof(buf), "%c%c%c %02x %s",
1.15      deraadt   268:                    sel & P5CTR_C ? 'c' : '-',
                    269:                    sel & P5CTR_U ? 'u' : '-',
                    270:                    sel & P5CTR_K ? 'k' : '-',
1.13      deraadt   271:                    fn, msg);
                    272:                break;
                    273:        case CPU_P6:
                    274:                cfnp = p6fn;
                    275:        case CPU_CORE:
1.14      deraadt   276:                if (cpu_type == CPU_CORE)
                    277:                        cfnp = corefn;
1.13      deraadt   278:                fn = sel & 0xff;
                    279:                if ((ind = pctr_ctrfn_index(cfnp, fn)) < 0)
                    280:                        msg = "unknown function";
                    281:                else
                    282:                        msg = cfnp[ind].name;
                    283:                if (cfnp[ind].name && cfnp[ind].flags & CFL_MESI)
                    284:                        snprintf(um, sizeof (um), "%c%c%c%c",
1.15      deraadt   285:                            sel & PCTR_UM_M ? 'M' : '-',
                    286:                            sel & PCTR_UM_E ? 'E' : '-',
                    287:                            sel & PCTR_UM_S ? 'S' : '-',
                    288:                            sel & PCTR_UM_I ? 'I' : '-');
1.13      deraadt   289:                else if (cfnp[ind].name && cfnp[ind].flags & CFL_SA)
                    290:                        snprintf(um, sizeof(um), "%c",
1.15      deraadt   291:                            sel & PCTR_UM_A ? 'A' : '-');
                    292:                if (sel >> PCTR_CM_SHIFT)
1.13      deraadt   293:                        snprintf(th, sizeof(th), "+%d",
1.15      deraadt   294:                            sel >> PCTR_CM_SHIFT);
1.13      deraadt   295:                snprintf(buf, sizeof(buf), "%c%c%c%c %02x %02x %s %s %s",
1.15      deraadt   296:                    sel & PCTR_I ? 'i' : '-',
                    297:                    sel & PCTR_E ? 'e' : '-',
                    298:                    sel & PCTR_K ? 'k' : '-',
                    299:                    sel & PCTR_U ? 'u' : '-',
                    300:                    fn, (sel >> PCTR_UM_SHIFT) & 0xff, th, um, msg);
1.13      deraadt   301:                break;
                    302:        case CPU_AMD:
                    303:                fn = sel & 0xff;
1.15      deraadt   304:                if (sel >> PCTR_CM_SHIFT)
1.13      deraadt   305:                        snprintf(th, sizeof(th), "+%d",
1.15      deraadt   306:                            sel >> PCTR_CM_SHIFT);
1.13      deraadt   307:                snprintf(buf, sizeof(buf), "%c%c%c%c %02x %02x %s",
1.15      deraadt   308:                    sel & PCTR_I ? 'i' : '-',
                    309:                    sel & PCTR_E ? 'e' : '-',
                    310:                    sel & PCTR_K ? 'k' : '-',
                    311:                    sel & PCTR_U ? 'u' : '-',
                    312:                    fn, (sel >> PCTR_UM_SHIFT) & 0xff, th);
1.13      deraadt   313:                break;
                    314:        }
                    315:        return (buf);
                    316: }
1.3       downsj    317:
1.1       dm        318: static void
1.13      deraadt   319: pctr_printvals(struct pctrst *st)
                    320: {
                    321:        int i, n;
                    322:
                    323:        switch (cpu_type) {
                    324:        case CPU_P5:
                    325:        case CPU_P6:
                    326:        case CPU_CORE:
                    327:                n = PCTR_INTEL_NUM;
                    328:        case CPU_AMD:
                    329:                if (cpu_type == CPU_AMD)
                    330:                        n = PCTR_AMD_NUM;
                    331:                for (i = 0; i < n; i++)
                    332:                        printf(" ctr%d = %16llu  [%s]\n", i, st->pctr_hwc[i],
                    333:                            pctr_fn2str(st->pctr_fn[i]));
                    334:                if (tsc_avail)
                    335:                        printf("  tsc = %16llu\n", st->pctr_tsc);
                    336:                break;
                    337:        }
                    338: }
                    339:
                    340: static int
                    341: pctr_read(struct pctrst *st)
                    342: {
                    343:        int fd, se;
                    344:
                    345:        fd = open(_PATH_PCTR, O_RDONLY);
                    346:        if (fd < 0)
                    347:                return (-1);
                    348:        if (ioctl(fd, PCIOCRD, st) < 0) {
                    349:                se = errno;
                    350:                close(fd);
                    351:                errno = se;
                    352:                return (-1);
                    353:        }
                    354:        return (close(fd));
                    355: }
                    356:
                    357: static int
                    358: pctr_write(int ctr, u_int32_t val)
                    359: {
                    360:        int fd, se;
                    361:
                    362:        fd = open(_PATH_PCTR, O_WRONLY);
                    363:        if (fd < 0)
                    364:                return (-1);
                    365:        if (ioctl(fd, PCIOCS0 + ctr, &val) < 0) {
                    366:                se = errno;
                    367:                close(fd);
                    368:                errno = se;
                    369:                return (-1);
                    370:        }
                    371:        return (close(fd));
                    372: }
                    373:
                    374: static __inline void
                    375: pctr_printdesc(char *desc)
1.1       dm        376: {
1.7       mickey    377:        char *p;
1.1       dm        378:
1.7       mickey    379:        for (;;) {
                    380:                while (*desc == ' ')
                    381:                        desc++;
                    382:                if (strlen(desc) < 70) {
                    383:                        if (*desc)
                    384:                                printf("      %s\n", desc);
                    385:                        return;
                    386:                }
                    387:                p = desc + 72;
                    388:                while (*--p != ' ')
                    389:                        ;
                    390:                while (*--p == ' ')
                    391:                        ;
                    392:                p++;
1.13      deraadt   393:                printf("      %.*s\n", (int)(p-desc), desc);
1.7       mickey    394:                desc = p;
                    395:        }
1.1       dm        396: }
                    397:
                    398: static void
1.13      deraadt   399: pctr_list_fnct(void)
1.1       dm        400: {
1.13      deraadt   401:        struct ctrfn *cfnp = NULL;
1.1       dm        402:
1.13      deraadt   403:        if (cpu_type == CPU_P5)
1.7       mickey    404:                cfnp = p5fn;
1.13      deraadt   405:        else if (cpu_type == CPU_P6)
1.7       mickey    406:                cfnp = p6fn;
1.13      deraadt   407:        else if (cpu_type == CPU_CORE)
                    408:                cfnp = corefn;
                    409:        else if (cpu_type == CPU_AMD)
                    410:                cfnp = amdfn;
                    411:        else
                    412:                return;
                    413:
1.7       mickey    414:        for (; cfnp->name; cfnp++) {
                    415:                printf("%02x  %s", cfnp->fn, cfnp->name);
                    416:                if (cfnp->flags & CFL_MESI)
1.13      deraadt   417:                        printf("  (MESI)");
1.7       mickey    418:                else if (cfnp->flags & CFL_SA)
1.13      deraadt   419:                        printf("  (A)");
1.7       mickey    420:                if (cfnp->flags & CFL_C0)
                    421:                        printf("  (ctr0 only)");
1.13      deraadt   422:                else if (cfnp->flags & CFL_C1)
1.7       mickey    423:                        printf("  (ctr1 only)");
1.18    ! mikeb     424:                if (cfnp->flags & CFL_UM)
        !           425:                        printf("  (needs unit mask)");
1.7       mickey    426:                printf("\n");
                    427:                if (cfnp->desc)
1.13      deraadt   428:                        pctr_printdesc(cfnp->desc);
1.7       mickey    429:        }
1.1       dm        430: }
                    431:
1.13      deraadt   432: static int
                    433: pctr_set_cntr(void)
1.1       dm        434: {
1.13      deraadt   435:        struct ctrfn *cfnp = NULL;
                    436:        u_int32_t val = func;
                    437:        int ind = 0;
                    438:
                    439:        switch (cpu_type) {
                    440:        case CPU_P5:
                    441:                if (ctr >= PCTR_INTEL_NUM)
1.18    ! mikeb     442:                        errx(1, "only %d counters are supported",
        !           443:                            PCTR_INTEL_NUM);
1.13      deraadt   444:                if (cflag)
1.15      deraadt   445:                        val |= P5CTR_C;
1.13      deraadt   446:                if (kflag)
1.15      deraadt   447:                        val |= P5CTR_K;
1.13      deraadt   448:                if (uflag)
1.15      deraadt   449:                        val |= P5CTR_U;
1.13      deraadt   450:                if (func && (!kflag && !uflag))
1.15      deraadt   451:                        val |= P5CTR_K | P5CTR_U;
1.13      deraadt   452:                break;
                    453:        case CPU_P6:
1.7       mickey    454:                cfnp = p6fn;
1.13      deraadt   455:        case CPU_CORE:
1.14      deraadt   456:                if (cpu_type == CPU_CORE)
                    457:                        cfnp = corefn;
1.13      deraadt   458:                if (ctr >= PCTR_INTEL_NUM)
1.18    ! mikeb     459:                        errx(1, "only %d counters are supported",
        !           460:                            PCTR_INTEL_NUM);
1.13      deraadt   461:                if (func && (ind = pctr_ctrfn_index(cfnp, func)) < 0)
1.18    ! mikeb     462:                        errx(1, "function %02x is not supported", func);
        !           463:                if (func && (cfnp[ind].flags & CFL_SA))
1.15      deraadt   464:                        val |= PCTR_UM_A;
1.18    ! mikeb     465:                if (func && (cfnp[ind].flags & CFL_MESI)) {
        !           466:                        if (Mflag)
        !           467:                                val |= PCTR_UM_M;
        !           468:                        if (Eflag)
        !           469:                                val |= PCTR_UM_E;
        !           470:                        if (Sflag)
        !           471:                                val |= PCTR_UM_S;
        !           472:                        if (Iflag)
        !           473:                                val |= PCTR_UM_I;
        !           474:                        if (!Mflag || !Eflag || !Sflag || !Iflag)
        !           475:                                val |= PCTR_UM_MESI;
        !           476:                }
1.13      deraadt   477:                if (func && (cfnp[ind].flags & CFL_ED))
1.15      deraadt   478:                        val |= PCTR_E;
1.18    ! mikeb     479:                if (func && (cfnp[ind].flags & CFL_UM) && !masku)
        !           480:                        errx(1, "function %02x needs unit mask specification",
        !           481:                            func);
1.13      deraadt   482:        case CPU_AMD:
                    483:                if (cpu_type == CPU_AMD && func &&
                    484:                    ((ind = pctr_ctrfn_index(amdfn, func)) < 0))
1.18    ! mikeb     485:                        errx(1, "function %02x is not supported", func);
1.13      deraadt   486:                if (ctr >= PCTR_AMD_NUM)
1.18    ! mikeb     487:                        errx(1, "only %d counters are supported",
        !           488:                            PCTR_AMD_NUM);
1.13      deraadt   489:                if (eflag)
1.15      deraadt   490:                        val |= PCTR_E;
1.13      deraadt   491:                if (iflag)
1.15      deraadt   492:                        val |= PCTR_I;
1.13      deraadt   493:                if (kflag)
1.15      deraadt   494:                        val |= PCTR_K;
1.13      deraadt   495:                if (uflag)
1.15      deraadt   496:                        val |= PCTR_U;
1.13      deraadt   497:                if (func && (!kflag && !uflag))
1.15      deraadt   498:                        val |= PCTR_K | PCTR_U;
                    499:                val |= masku << PCTR_UM_SHIFT;
                    500:                val |= thold << PCTR_CM_SHIFT;
1.13      deraadt   501:                if (func)
1.15      deraadt   502:                        val |= PCTR_EN;
1.13      deraadt   503:                break;
1.7       mickey    504:        }
                    505:
1.13      deraadt   506:        return (pctr_write(ctr, val));
1.1       dm        507: }
                    508:
                    509: static void
1.13      deraadt   510: usage(void)
1.1       dm        511: {
1.13      deraadt   512:        extern char *__progname;
                    513:        char *usg = NULL;
1.1       dm        514:
1.13      deraadt   515:        switch (cpu_type) {
                    516:        case CPU_P5:
1.17      mikeb     517:                usg = "[-cklu] [-f funct] [-s ctr]";
1.13      deraadt   518:                break;
                    519:        case CPU_P6:
                    520:        case CPU_CORE:
1.17      mikeb     521:                usg = "[-AEeIiklMSu] [-f funct] [-m umask] [-s ctr] "
1.13      deraadt   522:                    "[-t thold]";
                    523:                break;
                    524:        case CPU_AMD:
1.17      mikeb     525:                usg = "[-eilku] [-f funct] [-m umask] [-s ctr] "
1.13      deraadt   526:                    "[-t thold]";
                    527:                break;
1.7       mickey    528:        }
1.1       dm        529:
1.13      deraadt   530:        fprintf(stderr, "%s: %s\n", __progname, usg);
1.18    ! mikeb     531:        exit(1);
1.1       dm        532: }