Annotation of 43BSDReno/lib/libutil/kvm.c, revision 1.1.1.1

1.1       root        1: /*-
                      2:  * Copyright (c) 1989 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted provided
                      6:  * that: (1) source distributions retain this entire copyright notice and
                      7:  * comment, and (2) distributions including binaries display the following
                      8:  * acknowledgement:  ``This product includes software developed by the
                      9:  * University of California, Berkeley and its contributors'' in the
                     10:  * documentation or other materials provided with the distribution and in
                     11:  * all advertising materials mentioning features or use of this software.
                     12:  * Neither the name of the University nor the names of its contributors may
                     13:  * be used to endorse or promote products derived from this software without
                     14:  * specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
                     16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
                     17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #if defined(LIBC_SCCS) && !defined(lint)
                     21: static char sccsid[] = "@(#)kvm.c      5.9 (Berkeley) 6/27/90";
                     22: #endif /* LIBC_SCCS and not lint */
                     23: 
                     24: #include <machine/pte.h>
                     25: #include <machine/vmparam.h>
                     26: #include <sys/param.h>
                     27: #include <sys/user.h>
                     28: #include <sys/proc.h>
                     29: #include <sys/file.h>
                     30: #include <sys/text.h>
                     31: #include <sys/stat.h>
                     32: #include <sys/time.h>
                     33: #include <sys/vmmac.h>
                     34: #include <sys/ioctl.h>
                     35: #include <sys/tty.h>
                     36: #include <kvm.h>
                     37: #include <ctype.h>
                     38: #include <vis.h>
                     39: #include <nlist.h>
                     40: #include <pwd.h>
                     41: #include <string.h>
                     42: #include <ndbm.h>
                     43: #include <limits.h>
                     44: #include <paths.h>
                     45: #include <stdio.h>
                     46: 
                     47: /*
                     48:  * files
                     49:  */
                     50: static char *unixf, *memf, *kmemf, *swapf;
                     51: static int unixx, mem, kmem, swap;
                     52: static DBM *db;
                     53: /*
                     54:  * flags
                     55:  */
                     56: static int deadkernel;
                     57: static int kvminit = 0;
                     58: static int kvmfilesopen = 0;
                     59: /*
                     60:  * state
                     61:  */
                     62: static struct kinfo_proc *kvmprocbase, *kvmprocptr;
                     63: static int kvmnprocs;
                     64: /*
                     65:  * u. buffer
                     66:  */
                     67: static union {
                     68:        struct  user user;
                     69:        char    upages[UPAGES][NBPG];
                     70: } user;
                     71: /*
                     72:  * random other stuff
                     73:  */
                     74: static struct pte *Usrptmap, *usrpt;
                     75: static int     dmmin, dmmax;
                     76: static struct  pte *Sysmap;
                     77: static int     Syssize;
                     78: static int     pcbpf;
                     79: static int     argaddr0;       /* XXX */
                     80: static int     argaddr1;
                     81: static int     nswap;
                     82: static char    *tmp;
                     83: #if defined(hp300)
                     84: static int     lowram;
                     85: #endif
                     86: 
                     87: #define basename(cp)   ((tmp=rindex((cp), '/')) ? tmp+1 : (cp))
                     88: #define        MAXSYMSIZE      256
                     89: 
                     90: #if defined(hp300)
                     91: #define pftoc(f)       ((f) - lowram)
                     92: #define iskva(v)       (1)
                     93: #endif
                     94: 
                     95: #ifndef pftoc
                     96: #define pftoc(f)       (f)
                     97: #endif
                     98: #ifndef iskva
                     99: #define iskva(v)       ((v) & KERNBASE)
                    100: #endif
                    101: 
                    102: static struct nlist nl[] = {
                    103:        { "_Usrptmap" },
                    104: #define        X_USRPTMAP      0
                    105:        { "_usrpt" },
                    106: #define        X_USRPT         1
                    107:        { "_nswap" },
                    108: #define        X_NSWAP         2
                    109:        { "_dmmin" },
                    110: #define        X_DMMIN         3
                    111:        { "_dmmax" },
                    112: #define        X_DMMAX         4
                    113:        /*
                    114:         * everything here and down, only if a dead kernel
                    115:         */
                    116:        { "_Sysmap" },
                    117: #define        X_SYSMAP        5
                    118: #define        X_DEADKERNEL    X_SYSMAP
                    119:        { "_Syssize" },
                    120: #define        X_SYSSIZE       6
                    121:        { "_allproc" },
                    122: #define X_ALLPROC      7
                    123:        { "_zombproc" },
                    124: #define X_ZOMBPROC     8
                    125:        { "_nproc" },
                    126: #define        X_NPROC         9
                    127: #define        X_LAST          9
                    128: #if defined(hp300)
                    129:        { "_lowram" },
                    130: #define        X_LOWRAM        (X_LAST+1)
                    131: #endif
                    132:        { "" },
                    133: };
                    134: 
                    135: /*
                    136:  * returns     0 if files were opened now,
                    137:  *             1 if files were already opened,
                    138:  *             -1 if files could not be opened.
                    139:  */
                    140: kvm_openfiles(uf, mf, sf)
                    141:        char *uf, *mf, *sf; 
                    142: {
                    143:        if (kvmfilesopen)
                    144:                return (1);
                    145:        unixx = mem = kmem = swap = -1;
                    146:        unixf = (uf == NULL) ? _PATH_UNIX : uf; 
                    147:        memf = (mf == NULL) ? _PATH_MEM : mf;
                    148: 
                    149:        if ((unixx = open(unixf, O_RDONLY, 0)) == -1) {
                    150:                setsyserr("can't open %s", unixf);
                    151:                goto failed;
                    152:        }
                    153:        if ((mem = open(memf, O_RDONLY, 0)) == -1) {
                    154:                setsyserr("can't open %s", memf);
                    155:                goto failed;
                    156:        }
                    157:        if (sf != NULL)
                    158:                swapf = sf;
                    159:        if (mf != NULL) {
                    160:                deadkernel++;
                    161:                kmemf = mf;
                    162:                kmem = mem;
                    163:                swap = -1;
                    164:        } else {
                    165:                kmemf = _PATH_KMEM;
                    166:                if ((kmem = open(kmemf, O_RDONLY, 0)) == -1) {
                    167:                        setsyserr("can't open %s", kmemf);
                    168:                        goto failed;
                    169:                }
                    170:                swapf = (sf == NULL) ?  _PATH_DRUM : sf;
                    171:                /*
                    172:                 * live kernel - avoid looking up nlist entries
                    173:                 * past X_DEADKERNEL.
                    174:                 */
                    175:                nl[X_DEADKERNEL].n_name = "";
                    176:        }
                    177:        if (swapf != NULL && ((swap = open(swapf, O_RDONLY, 0)) == -1)) {
                    178:                seterr("can't open %s", swapf);
                    179:                goto failed;
                    180:        }
                    181:        kvmfilesopen++;
                    182:        if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1) /*XXX*/
                    183:                return (-1);
                    184:        return (0);
                    185: failed:
                    186:        kvm_close();
                    187:        return (-1);
                    188: }
                    189: 
                    190: static
                    191: kvm_init(uf, mf, sf)
                    192:        char *uf, *mf, *sf;
                    193: {
                    194:        if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1)
                    195:                return (-1);
                    196:        if (getkvars() == -1)
                    197:                return (-1);
                    198:        kvminit = 1;
                    199: 
                    200:        return (0);
                    201: }
                    202: 
                    203: kvm_close()
                    204: {
                    205:        if (unixx != -1) {
                    206:                close(unixx);
                    207:                unixx = -1;
                    208:        }
                    209:        if (kmem != -1) {
                    210:                if (kmem != mem)
                    211:                        close(kmem);
                    212:                /* otherwise kmem is a copy of mem, and will be closed below */
                    213:                kmem = -1;
                    214:        }
                    215:        if (mem != -1) {
                    216:                close(mem);
                    217:                mem = -1;
                    218:        }
                    219:        if (swap != -1) {
                    220:                close(swap);
                    221:                swap = -1;
                    222:        }
                    223:        if (db != NULL) {
                    224:                dbm_close(db);
                    225:                db = NULL;
                    226:        }
                    227:        kvminit = 0;
                    228:        kvmfilesopen = 0;
                    229:        deadkernel = 0;
                    230:        if (Sysmap) {
                    231:                free(Sysmap);
                    232:                Sysmap = NULL;
                    233:        }
                    234: }
                    235: 
                    236: kvm_nlist(nl)
                    237:        struct nlist *nl;
                    238: {
                    239:        datum key, data;
                    240:        char dbname[MAXPATHLEN];
                    241:        char dbversion[_BSD_LINE_MAX];
                    242:        char kversion[_BSD_LINE_MAX];
                    243:        int dbversionlen;
                    244:        char symbuf[MAXSYMSIZE+1];
                    245:        struct nlist nbuf, *n;
                    246:        int num, did;
                    247: 
                    248:        if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1)
                    249:                return (-1);
                    250:        if (deadkernel)
                    251:                goto hard2;
                    252:        /*
                    253:         * initialize key datum
                    254:         */
                    255:        key.dptr = symbuf;
                    256:        symbuf[0] = KVMDB_NLIST;
                    257: 
                    258:        if (db != NULL)
                    259:                goto win;       /* off to the races */
                    260:        /*
                    261:         * open database
                    262:         */
                    263:        sprintf(dbname, "%s/kvm_%s", KVMDBDIR, basename(unixf));
                    264:        if ((db = dbm_open(dbname, O_RDONLY, 0)) == NULL)
                    265:                goto hard2;
                    266:        /*
                    267:         * read version out of database
                    268:         */
                    269:        bcopy("VERSION", symbuf+1, sizeof ("VERSION")-1);
                    270:        key.dsize = (sizeof ("VERSION") - 1) + 1;
                    271:        data = dbm_fetch(db, key);
                    272:        if (data.dptr == NULL)
                    273:                goto hard1;
                    274:        bcopy(data.dptr, dbversion, data.dsize);
                    275:        dbversionlen = data.dsize;
                    276:        /*
                    277:         * read version string from kernel memory
                    278:         */
                    279:        bcopy("_version", symbuf+1, sizeof ("_version")-1);
                    280:        key.dsize = (sizeof ("_version")-1) + 1;
                    281:        data = dbm_fetch(db, key);
                    282:        if (data.dptr == NULL)
                    283:                goto hard1;
                    284:        if (data.dsize != sizeof (struct nlist))
                    285:                goto hard1;
                    286:        bcopy(data.dptr, &nbuf, sizeof (struct nlist));
                    287:        lseek(kmem, nbuf.n_value, 0);
                    288:        if (read(kmem, kversion, dbversionlen) != dbversionlen)
                    289:                goto hard1;
                    290:        /*
                    291:         * if they match, we win - otherwise do it the hard way
                    292:         */
                    293:        if (bcmp(dbversion, kversion, dbversionlen) != 0)
                    294:                goto hard1;
                    295:        /*
                    296:         * getem from the database.
                    297:         */
                    298: win:
                    299:        num = did = 0;
                    300:        for (n = nl; n->n_name && n->n_name[0]; n++, num++) {
                    301:                int len;
                    302:                /*
                    303:                 * clear out fields from users buffer
                    304:                 */
                    305:                n->n_type = 0;
                    306:                n->n_other = 0;
                    307:                n->n_desc = 0;
                    308:                n->n_value = 0;
                    309:                /*
                    310:                 * query db
                    311:                 */
                    312:                if ((len = strlen(n->n_name)) > MAXSYMSIZE) {
                    313:                        seterr("kvm_nlist: symbol too large");
                    314:                        return (-1);
                    315:                }
                    316:                strcpy(symbuf+1, n->n_name);
                    317:                key.dsize = len + 1;
                    318:                data = dbm_fetch(db, key);
                    319:                if (data.dptr == NULL || data.dsize != sizeof (struct nlist))
                    320:                        continue;
                    321:                bcopy(data.dptr, &nbuf, sizeof (struct nlist));
                    322:                n->n_value = nbuf.n_value;
                    323:                n->n_type = nbuf.n_type;
                    324:                n->n_desc = nbuf.n_desc;
                    325:                n->n_other = nbuf.n_other;
                    326:                did++;
                    327:        }
                    328:        return (num - did);
                    329: hard1:
                    330:        dbm_close(db);
                    331:        db = NULL;
                    332: hard2:
                    333:        return (nlist(unixf, nl));      /* XXX seterr if -1 */
                    334: }
                    335: 
                    336: kvm_getprocs(what, arg)
                    337: {
                    338:        if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
                    339:                return (NULL);
                    340:        if (!deadkernel) {
                    341:                int ret, copysize;
                    342: 
                    343:                if ((ret = getkerninfo(what, NULL, NULL, arg)) == -1) {
                    344:                        setsyserr("can't get estimate for kerninfo");
                    345:                        return (-1);
                    346:                }
                    347:                copysize = ret;
                    348:                if ((kvmprocbase = (struct kinfo_proc *)malloc(copysize)) 
                    349:                     == NULL) {
                    350:                        seterr("out of memory");
                    351:                        return (-1);
                    352:                }
                    353:                if ((ret = getkerninfo(what, kvmprocbase, &copysize, 
                    354:                     arg)) == -1) {
                    355:                        setsyserr("can't get proc list");
                    356:                        return (-1);
                    357:                }
                    358:                if (copysize % sizeof (struct kinfo_proc)) {
                    359:                        seterr("proc size mismatch (kinfo_proc: %d)",
                    360:                                sizeof (struct kinfo_proc));
                    361:                        return (-1);
                    362:                }
                    363:                kvmnprocs = copysize / sizeof (struct kinfo_proc);
                    364:        } else {
                    365:                int nproc;
                    366: 
                    367:                if (kvm_read(nl[X_NPROC].n_value, &nproc, sizeof (int)) !=
                    368:                    sizeof (int)) {
                    369:                        seterr("can't read nproc");
                    370:                        return (-1);
                    371:                }
                    372:                if ((kvmprocbase = (struct kinfo_proc *)
                    373:                     malloc(nproc * sizeof (struct kinfo_proc))) == NULL) {
                    374:                        seterr("out of memory (addr: %x nproc = %d)",
                    375:                                nl[X_NPROC].n_value, nproc);
                    376:                        return (-1);
                    377:                }
                    378:                kvmnprocs = kvm_doprocs(what, arg, kvmprocbase);
                    379:                realloc(kvmprocbase, kvmnprocs * sizeof (struct kinfo_proc));
                    380:        }
                    381:        kvmprocptr = kvmprocbase;
                    382: 
                    383:        return (kvmnprocs);
                    384: }
                    385: 
                    386: /*
                    387:  * XXX - should NOT give up so easily - especially since the kernel
                    388:  * may be corrupt (it died).  Should gather as much information as possible.
                    389:  * Follows proc ptrs instead of reading table since table may go
                    390:  * away soon.
                    391:  */
                    392: static
                    393: kvm_doprocs(what, arg, buff)
                    394:        int what, arg;
                    395:        char *buff;
                    396: {
                    397:        struct proc *p, proc;
                    398:        register char *bp = buff;
                    399:        int i = 0;
                    400:        int doingzomb = 0;
                    401:        struct eproc eproc;
                    402:        struct pgrp pgrp;
                    403:        struct session sess;
                    404:        struct tty tty;
                    405:        struct text text;
                    406: 
                    407:        /* allproc */
                    408:        if (kvm_read(nl[X_ALLPROC].n_value, &p, 
                    409:            sizeof (struct proc *)) != sizeof (struct proc *)) {
                    410:                seterr("can't read allproc");
                    411:                return (-1);
                    412:        }
                    413: 
                    414: again:
                    415:        for (; p; p = proc.p_nxt) {
                    416:                if (kvm_read(p, &proc, sizeof (struct proc)) !=
                    417:                    sizeof (struct proc)) {
                    418:                        seterr("can't read proc at %x", p);
                    419:                        return (-1);
                    420:                }
                    421:                switch(ki_op(what)) {
                    422:                        
                    423:                case KINFO_PROC_PID:
                    424:                        if (proc.p_pid != (pid_t)arg)
                    425:                                continue;
                    426:                        break;
                    427: 
                    428: 
                    429:                case KINFO_PROC_UID:
                    430:                        if (proc.p_uid != (uid_t)arg)
                    431:                                continue;
                    432:                        break;
                    433: 
                    434:                case KINFO_PROC_RUID:
                    435:                        if (proc.p_ruid != (uid_t)arg)
                    436:                                continue;
                    437:                        break;
                    438:                }
                    439:                /*
                    440:                 * gather eproc
                    441:                 */
                    442:                eproc.e_paddr = p;
                    443:                if (kvm_read(proc.p_pgrp, &pgrp, sizeof (struct pgrp)) !=
                    444:                    sizeof (struct pgrp)) {
                    445:                        seterr("can't read pgrp at %x", proc.p_pgrp);
                    446:                        return (-1);
                    447:                }
                    448:                eproc.e_sess = pgrp.pg_session;
                    449:                eproc.e_pgid = pgrp.pg_id;
                    450:                eproc.e_jobc = pgrp.pg_jobc;
                    451:                if (kvm_read(pgrp.pg_session, &sess, sizeof (struct session))
                    452:                   != sizeof (struct session)) {
                    453:                        seterr("can't read session at %x", pgrp.pg_session);
                    454:                        return (-1);
                    455:                }
                    456:                if ((proc.p_flag&SCTTY) && sess.s_ttyp != NULL) {
                    457:                        if (kvm_read(sess.s_ttyp, &tty, sizeof (struct tty))
                    458:                            != sizeof (struct tty)) {
                    459:                                seterr("can't read tty at %x", sess.s_ttyp);
                    460:                                return (-1);
                    461:                        }
                    462:                        eproc.e_tdev = tty.t_dev;
                    463:                        eproc.e_tsess = tty.t_session;
                    464:                        if (tty.t_pgrp != NULL) {
                    465:                                if (kvm_read(tty.t_pgrp, &pgrp, sizeof (struct
                    466:                                    pgrp)) != sizeof (struct pgrp)) {
                    467:                                        seterr("can't read tpgrp at &x", 
                    468:                                                tty.t_pgrp);
                    469:                                        return (-1);
                    470:                                }
                    471:                                eproc.e_tpgid = pgrp.pg_id;
                    472:                        } else
                    473:                                eproc.e_tpgid = -1;
                    474:                } else
                    475:                        eproc.e_tdev = NODEV;
                    476:                if (proc.p_wmesg)
                    477:                        kvm_read(proc.p_wmesg, eproc.e_wmesg, WMESGLEN);
                    478:                if (proc.p_textp) {
                    479:                        kvm_read(proc.p_textp, &text, sizeof (text));
                    480:                        eproc.e_xsize = text.x_size;
                    481:                        eproc.e_xrssize = text.x_rssize;
                    482:                        eproc.e_xccount = text.x_ccount;
                    483:                        eproc.e_xswrss = text.x_swrss;
                    484:                } else {
                    485:                        eproc.e_xsize = eproc.e_xrssize =
                    486:                          eproc.e_xccount = eproc.e_xswrss = 0;
                    487:                }
                    488: 
                    489:                switch(ki_op(what)) {
                    490: 
                    491:                case KINFO_PROC_PGRP:
                    492:                        if (eproc.e_pgid != (pid_t)arg)
                    493:                                continue;
                    494:                        break;
                    495: 
                    496:                case KINFO_PROC_TTY:
                    497:                        if ((proc.p_flag&SCTTY) == 0 || 
                    498:                             eproc.e_tdev != (dev_t)arg)
                    499:                                continue;
                    500:                        break;
                    501:                }
                    502: 
                    503:                i++;
                    504:                bcopy(&proc, bp, sizeof (struct proc));
                    505:                bp += sizeof (struct proc);
                    506:                bcopy(&eproc, bp, sizeof (struct eproc));
                    507:                bp+= sizeof (struct eproc);
                    508:        }
                    509:        if (!doingzomb) {
                    510:                /* zombproc */
                    511:                if (kvm_read(nl[X_ZOMBPROC].n_value, &p, 
                    512:                    sizeof (struct proc *)) != sizeof (struct proc *)) {
                    513:                        seterr("can't read zombproc");
                    514:                        return (-1);
                    515:                }
                    516:                doingzomb = 1;
                    517:                goto again;
                    518:        }
                    519: 
                    520:        return (i);
                    521: }
                    522: 
                    523: struct proc *
                    524: kvm_nextproc()
                    525: {
                    526: 
                    527:        if (!kvmprocbase && kvm_getprocs(0, 0) == -1)
                    528:                return (NULL);
                    529:        if (kvmprocptr >= (kvmprocbase + kvmnprocs)) {
                    530:                seterr("end of proc list");
                    531:                return (NULL);
                    532:        }
                    533:        return((struct proc *)(kvmprocptr++));
                    534: }
                    535: 
                    536: struct eproc *
                    537: kvm_geteproc(p)
                    538:        struct proc *p;
                    539: {
                    540:        return ((struct eproc *)(((char *)p) + sizeof (struct proc)));
                    541: }
                    542: 
                    543: kvm_setproc()
                    544: {
                    545: 
                    546:        kvmprocptr = kvmprocbase;
                    547: }
                    548: 
                    549: kvm_freeprocs()
                    550: {
                    551: 
                    552:        if (kvmprocbase) {
                    553:                free(kvmprocbase);
                    554:                kvmprocbase = NULL;
                    555:        }
                    556: }
                    557: 
                    558: struct user *
                    559: kvm_getu(p)
                    560:        struct proc *p;
                    561: {
                    562:        struct pte *pteaddr, apte;
                    563:        struct pte arguutl[HIGHPAGES+(CLSIZE*2)];
                    564:        register int i;
                    565:        int ncl;
                    566: 
                    567:        if (kvminit == 0 && kvm_init(NULL, NULL, NULL, 0) == -1)
                    568:                return (NULL);
                    569:        if (p->p_stat == SZOMB) {
                    570:                seterr("zombie process");
                    571:                return (NULL);
                    572:        }
                    573:        if ((p->p_flag & SLOAD) == 0) {
                    574:                if (swap < 0) {
                    575:                        seterr("no swap");
                    576:                        return (NULL);
                    577:                }
                    578:                (void) lseek(swap, (long)dtob(p->p_swaddr), 0);
                    579:                if (read(swap, (char *)&user.user, sizeof (struct user)) != 
                    580:                    sizeof (struct user)) {
                    581:                        seterr("can't read u for pid %d from %s\n",
                    582:                            p->p_pid, swapf);
                    583:                        return (NULL);
                    584:                }
                    585:                pcbpf = 0;
                    586:                argaddr0 = 0;
                    587:                argaddr1 = 0;
                    588:                return (&user.user);
                    589:        }
                    590:        pteaddr = &Usrptmap[btokmx(p->p_p0br) + p->p_szpt - 1];
                    591:        klseek(kmem, (long)pteaddr, 0);
                    592:        if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
                    593:                seterr("can't read indir pte to get u for pid %d from %s",
                    594:                    p->p_pid, kmemf);
                    595:                return (NULL);
                    596:        }
                    597:        lseek(mem, (long)ctob(pftoc(apte.pg_pfnum+1)) - sizeof(arguutl), 0);
                    598:        if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
                    599:                seterr("can't read page table for u of pid %d from %s",
                    600:                    p->p_pid, memf);
                    601:                return (NULL);
                    602:        }
                    603:        if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
                    604:                argaddr0 = ctob(pftoc(arguutl[0].pg_pfnum));
                    605:        else
                    606:                argaddr0 = 0;
                    607:        if (arguutl[CLSIZE*1].pg_fod == 0 && arguutl[CLSIZE*1].pg_pfnum)
                    608:                argaddr1 = ctob(pftoc(arguutl[CLSIZE*1].pg_pfnum));
                    609:        else
                    610:                argaddr1 = 0;
                    611:        pcbpf = arguutl[CLSIZE*2].pg_pfnum;
                    612:        ncl = (sizeof (struct user) + CLBYTES - 1) / CLBYTES;
                    613:        while (--ncl >= 0) {
                    614:                i = ncl * CLSIZE;
                    615:                lseek(mem,
                    616:                      (long)ctob(pftoc(arguutl[(CLSIZE*2)+i].pg_pfnum)), 0);
                    617:                if (read(mem, user.upages[i], CLBYTES) != CLBYTES) {
                    618:                        seterr("can't read page %d of u of pid %d from %s",
                    619:                            arguutl[(CLSIZE*2)+i].pg_pfnum, p->p_pid, memf);
                    620:                        return(NULL);
                    621:                }
                    622:        }
                    623:        return (&user.user);
                    624: }
                    625: 
                    626: char *
                    627: kvm_getargs(p, up)
                    628:        struct proc *p;
                    629:        struct user *up;
                    630: {
                    631:        char cmdbuf[CLBYTES*2];
                    632:        union {
                    633:                char    argc[CLBYTES*2];
                    634:                int     argi[CLBYTES*2/sizeof (int)];
                    635:        } argspac;
                    636:        register char *cp;
                    637:        register int *ip;
                    638:        char c;
                    639:        int nbad;
                    640:        struct dblock db;
                    641:        char *file;
                    642: 
                    643:        if (up == NULL || p->p_pid == 0 || p->p_pid == 2)
                    644:                goto retucomm;
                    645:        if ((p->p_flag & SLOAD) == 0 || argaddr1 == 0) {
                    646:                if (swap < 0 || p->p_ssize == 0)
                    647:                        goto retucomm;
                    648:                vstodb(0, CLSIZE, &up->u_smap, &db, 1);
                    649:                (void) lseek(swap, (long)dtob(db.db_base), 0);
                    650:                if (read(swap, (char *)&argspac.argc[CLBYTES], CLBYTES)
                    651:                        != CLBYTES)
                    652:                        goto bad;
                    653:                vstodb(1, CLSIZE, &up->u_smap, &db, 1);
                    654:                (void) lseek(swap, (long)dtob(db.db_base), 0);
                    655:                if (read(swap, (char *)&argspac.argc[0], CLBYTES) != CLBYTES)
                    656:                        goto bad;
                    657:                file = swapf;
                    658:        } else {
                    659:                if (argaddr0) {
                    660:                        lseek(mem, (long)argaddr0, 0);
                    661:                        if (read(mem, (char *)&argspac, CLBYTES) != CLBYTES)
                    662:                                goto bad;
                    663:                } else
                    664:                        bzero(&argspac, CLBYTES);
                    665:                lseek(mem, (long)argaddr1, 0);
                    666:                if (read(mem, &argspac.argc[CLBYTES], CLBYTES) != CLBYTES)
                    667:                        goto bad;
                    668:                file = memf;
                    669:        }
                    670:        ip = &argspac.argi[CLBYTES*2/sizeof (int)];
                    671:        ip -= 2;                /* last arg word and .long 0 */
                    672:        while (*--ip) {
                    673:                if (ip == argspac.argi)
                    674:                        goto retucomm;
                    675:        }
                    676:        *(char *)ip = ' ';
                    677:        ip++;
                    678:        nbad = 0;
                    679:        for (cp = (char *)ip; cp < &argspac.argc[CLBYTES*2]; cp++) {
                    680:                c = *cp & 0177;
                    681:                if (c == 0)
                    682:                        *cp = ' ';
                    683:                else if (c < ' ' || c > 0176) {
                    684:                        if (++nbad >= 5*(0+1)) {        /* eflg -> 0 XXX */
                    685:                                *cp++ = ' ';
                    686:                                break;
                    687:                        }
                    688:                        *cp = '?';
                    689:                } else if (0 == 0 && c == '=') {        /* eflg -> 0 XXX */
                    690:                        while (*--cp != ' ')
                    691:                                if (cp <= (char *)ip)
                    692:                                        break;
                    693:                        break;
                    694:                }
                    695:        }
                    696:        *cp = 0;
                    697:        while (*--cp == ' ')
                    698:                *cp = 0;
                    699:        cp = (char *)ip;
                    700:        (void) strncpy(cmdbuf, cp, &argspac.argc[CLBYTES*2] - cp);
                    701:        if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
                    702:                (void) strcat(cmdbuf, " (");
                    703:                (void) strncat(cmdbuf, p->p_comm, sizeof(p->p_comm));
                    704:                (void) strcat(cmdbuf, ")");
                    705:        }
                    706:        return (cmdbuf);
                    707: 
                    708: bad:
                    709:        seterr("error locating command name for pid %d from %s\n",
                    710:            p->p_pid, file);
                    711: retucomm:
                    712:        (void) strcpy(cmdbuf, " (");
                    713:        (void) strncat(cmdbuf, p->p_comm, sizeof (p->p_comm));
                    714:        (void) strcat(cmdbuf, ")");
                    715:        return (cmdbuf);
                    716: }
                    717: 
                    718: 
                    719: static
                    720: getkvars()
                    721: {
                    722: 
                    723:        if (kvm_nlist(nl) == -1)
                    724:                return (-1);
                    725:        if (deadkernel) {
                    726:                /* We must do the sys map first because klseek uses it */
                    727:                long    addr;
                    728: 
                    729:                Syssize = nl[X_SYSSIZE].n_value;
                    730:                Sysmap = (struct pte *)
                    731:                        calloc((unsigned) Syssize, sizeof (struct pte));
                    732:                if (Sysmap == NULL) {
                    733:                        seterr("out of space for Sysmap");
                    734:                        return (-1);
                    735:                }
                    736:                addr = (long) nl[X_SYSMAP].n_value;
                    737:                addr &= ~KERNBASE;
                    738:                (void) lseek(kmem, addr, 0);
                    739:                if (read(kmem, (char *) Sysmap, Syssize * sizeof (struct pte))
                    740:                    != Syssize * sizeof (struct pte)) {
                    741:                        seterr("can't read Sysmap");
                    742:                        return (-1);
                    743:                }
                    744: #if defined(hp300)
                    745:                addr = (long) nl[X_LOWRAM].n_value;
                    746:                (void) lseek(kmem, addr, 0);
                    747:                if (read(kmem, (char *) &lowram, sizeof (lowram))
                    748:                    != sizeof (lowram)) {
                    749:                        seterr("can't read lowram");
                    750:                        return (-1);
                    751:                }
                    752:                lowram = btop(lowram);
                    753: #endif
                    754:        }
                    755:        usrpt = (struct pte *)nl[X_USRPT].n_value;
                    756:        Usrptmap = (struct pte *)nl[X_USRPTMAP].n_value;
                    757:        if (kvm_read((long)nl[X_NSWAP].n_value, &nswap, sizeof (long)) !=
                    758:            sizeof (long)) {
                    759:                seterr("can't read nswap");
                    760:                return (-1);
                    761:        }
                    762:        if (kvm_read((long)nl[X_DMMIN].n_value, &dmmin, sizeof (long)) !=
                    763:            sizeof (long)) {
                    764:                seterr("can't read dmmin");
                    765:                return (-1);
                    766:        }
                    767:        if (kvm_read((long)nl[X_DMMAX].n_value, &dmmax, sizeof (long)) !=
                    768:            sizeof (long)) {
                    769:                seterr("can't read dmmax");
                    770:                return (-1);
                    771:        }
                    772:        return (0);
                    773: }
                    774: 
                    775: kvm_read(loc, buf, len)
                    776:        unsigned long loc;
                    777:        char *buf;
                    778: {
                    779:        if (kvmfilesopen == 0 && kvm_openfiles(NULL, NULL, NULL) == -1)
                    780:                return (-1);
                    781:        if (iskva(loc)) {
                    782:                klseek(kmem, loc, 0);
                    783:                if (read(kmem, buf, len) != len) {
                    784:                        seterr("error reading kmem at %x\n", loc);
                    785:                        return (-1);
                    786:                }
                    787:        } else {
                    788:                lseek(mem, loc, 0);
                    789:                if (read(mem, buf, len) != len) {
                    790:                        seterr("error reading mem at %x\n", loc);
                    791:                        return (-1);
                    792:                }
                    793:        }
                    794:        return (len);
                    795: }
                    796: 
                    797: static
                    798: klseek(fd, loc, off)
                    799:        int fd;
                    800:        off_t loc;
                    801:        int off;
                    802: {
                    803: 
                    804:        if (deadkernel) {
                    805:                off_t vtophys();
                    806: 
                    807:                if ((loc = vtophys(loc)) == -1)
                    808:                        return;
                    809:        }
                    810:        (void) lseek(fd, (off_t)loc, off);
                    811: }
                    812: 
                    813: /*
                    814:  * Given a base/size pair in virtual swap area,
                    815:  * return a physical base/size pair which is the
                    816:  * (largest) initial, physically contiguous block.
                    817:  */
                    818: static
                    819: vstodb(vsbase, vssize, dmp, dbp, rev)
                    820:        register int vsbase;
                    821:        int vssize;
                    822:        struct dmap *dmp;
                    823:        register struct dblock *dbp;
                    824: {
                    825:        register int blk = dmmin;
                    826:        register swblk_t *ip = dmp->dm_map;
                    827: 
                    828:        vsbase = ctod(vsbase);
                    829:        vssize = ctod(vssize);
                    830:        if (vsbase < 0 || vsbase + vssize > dmp->dm_size)
                    831:                /*panic("vstodb")*/;
                    832:        while (vsbase >= blk) {
                    833:                vsbase -= blk;
                    834:                if (blk < dmmax)
                    835:                        blk *= 2;
                    836:                ip++;
                    837:        }
                    838:        if (*ip <= 0 || *ip + blk > nswap)
                    839:                /*panic("vstodb")*/;
                    840:        dbp->db_size = MIN(vssize, blk - vsbase);
                    841:        dbp->db_base = *ip + (rev ? blk - (vsbase + dbp->db_size) : vsbase);
                    842: }
                    843: 
                    844: static off_t
                    845: vtophys(loc)
                    846:        long loc;
                    847: {
                    848:        int p;
                    849:        off_t newloc;
                    850:        register struct pte *pte;
                    851: 
                    852:        newloc = loc & ~KERNBASE;
                    853:        p = btop(newloc);
                    854: #if defined(vax) || defined(tahoe)
                    855:        if ((loc & KERNBASE) == 0) {
                    856:                seterr("vtophys: translating non-kernel address");
                    857:                return((off_t) -1);
                    858:        }
                    859: #endif
                    860:        if (p >= Syssize) {
                    861:                seterr("vtophys: page out of bound (%d>=%d)", p, Syssize);
                    862:                return((off_t) -1);
                    863:        }
                    864:        pte = &Sysmap[p];
                    865:        if (pte->pg_v == 0 && (pte->pg_fod || pte->pg_pfnum == 0)) {
                    866:                seterr("vtophys: page not valid");
                    867:                return((off_t) -1);
                    868:        }
                    869: #if defined(hp300)
                    870:        if (pte->pg_pfnum < lowram) {
                    871:                seterr("vtophys: non-RAM page (%d<%d)", pte->pg_pfnum, lowram);
                    872:                return((off_t) -1);
                    873:        }
                    874: #endif
                    875:        loc = (long) (ptob(pftoc(pte->pg_pfnum)) + (loc & PGOFSET));
                    876:        return(loc);
                    877: }
                    878: 
                    879: #include <varargs.h>
                    880: static char errbuf[_BSD_LINE_MAX];
                    881: 
                    882: static
                    883: seterr(va_alist)
                    884:        va_dcl
                    885: {
                    886:        char *fmt;
                    887:        va_list ap;
                    888: 
                    889:        va_start(ap);
                    890:        fmt = va_arg(ap, char *);
                    891:        (void) vsprintf(errbuf, fmt, ap);
                    892:        va_end(ap);
                    893: }
                    894: 
                    895: static
                    896: setsyserr(va_alist)
                    897:        va_dcl
                    898: {
                    899:        char *fmt, *cp;
                    900:        va_list ap;
                    901:        extern int errno;
                    902: 
                    903:        va_start(ap);
                    904:        fmt = va_arg(ap, char *);
                    905:        (void) vsprintf(errbuf, fmt, ap);
                    906:        for (cp=errbuf; *cp; cp++)
                    907:                ;
                    908:        sprintf(cp, ": %s", strerror(errno));
                    909:        va_end(ap);
                    910: }
                    911: 
                    912: char *
                    913: kvm_geterr()
                    914: {
                    915:        return (errbuf);
                    916: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.