Annotation of 43BSDReno/lib/libutil/kvm.c, revision 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.