Annotation of 42BSD/bin/adb/access.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)access.c   4.7 8/11/83";
        !             3: #endif
        !             4: /*
        !             5:  * Adb: access data in file/process address space.
        !             6:  *
        !             7:  * The routines in this file access referenced data using
        !             8:  * the maps to access files, ptrace to access subprocesses,
        !             9:  * or the system page tables when debugging the kernel,
        !            10:  * to translate virtual to physical addresses.
        !            11:  */
        !            12: 
        !            13: #include "defs.h"
        !            14: 
        !            15: 
        !            16: MAP            txtmap;
        !            17: MAP            datmap;
        !            18: INT            wtflag;
        !            19: STRING         errflg;
        !            20: INT            errno;
        !            21: 
        !            22: INT            pid;
        !            23: 
        !            24: /*
        !            25:  * Primitives: put a value in a space, get a value from a space
        !            26:  * and get a word or byte not returning if an error occurred.
        !            27:  */
        !            28: put(addr, space, value) 
        !            29:     off_t addr; { (void) access(WT, addr, space, value); }
        !            30: 
        !            31: u_int
        !            32: get(addr, space)
        !            33:     off_t addr; { return (access(RD, addr, space, 0)); };
        !            34: 
        !            35: u_int
        !            36: chkget(addr, space)
        !            37:     off_t addr; { u_int w = get(addr, space); chkerr(); return(w); }
        !            38: 
        !            39: u_int
        !            40: bchkget(addr, space) 
        !            41:     off_t addr; { return(chkget(addr, space) & LOBYTE); }
        !            42: 
        !            43: /*
        !            44:  * Read/write according to mode at address addr in i/d space.
        !            45:  * Value is quantity to be written, if write.
        !            46:  *
        !            47:  * This routine decides whether to get the data from the subprocess
        !            48:  * address space with ptrace, or to get it from the files being
        !            49:  * debugged.  
        !            50:  *
        !            51:  * When the kernel is being debugged with the -k flag we interpret
        !            52:  * the system page tables for data space, mapping p0 and p1 addresses
        !            53:  * relative to the ``current'' process (as specified by its p_addr in
        !            54:  * <p) and mapping system space addresses through the system page tables.
        !            55:  */
        !            56: access(mode, addr, space, value)
        !            57:        int mode, space, value;
        !            58:        off_t addr;
        !            59: {
        !            60:        int rd = mode == RD;
        !            61:        int file, w;
        !            62: 
        !            63:        if (space == NSP)
        !            64:                return(0);
        !            65:        if (pid) {
        !            66:                int pmode = (space&DSP?(rd?RDUSER:WDUSER):(rd?RIUSER:WIUSER));
        !            67: 
        !            68:                w = ptrace(pmode, pid, addr, value);
        !            69:                if (errno)
        !            70:                        rwerr(space);
        !            71:                return (w);
        !            72:        }
        !            73:        w = 0;
        !            74:        if (mode==WT && wtflag==0)
        !            75:                error("not in write mode");
        !            76:        if (!chkmap(&addr, space))
        !            77:                return (0);
        !            78:        file = (space&DSP) ? datmap.ufd : txtmap.ufd;
        !            79:        if (kernel && space == DSP) {
        !            80:                addr = vtophys(addr);
        !            81:                if (addr < 0)
        !            82:                        return (0);
        !            83:        }
        !            84:        if (physrw(file, addr, rd ? &w : &value, rd) < 0)
        !            85:                rwerr(space);
        !            86:        return (w);
        !            87: }
        !            88: 
        !            89: /*
        !            90:  * When looking at kernel data space through /dev/mem or
        !            91:  * with a core file, do virtual memory mapping.
        !            92:  */
        !            93: vtophys(addr)
        !            94:        off_t addr;
        !            95: {
        !            96:        int oldaddr = addr;
        !            97:        int v;
        !            98:        struct pte pte;
        !            99: 
        !           100:        addr &= ~0xc0000000;
        !           101:        v = btop(addr);
        !           102:        switch (oldaddr&0xc0000000) {
        !           103: 
        !           104:        case 0xc0000000:
        !           105:        case 0x80000000:
        !           106:                /*
        !           107:                 * In system space get system pte.  If
        !           108:                 * valid or reclaimable then physical address
        !           109:                 * is combination of its page number and the page
        !           110:                 * offset of the original address.
        !           111:                 */
        !           112:                if (v >= slr)
        !           113:                        goto oor;
        !           114:                addr = ((long)(sbr+v)) &~ 0x80000000;
        !           115:                goto simple;
        !           116: 
        !           117:        case 0x40000000:
        !           118:                /*
        !           119:                 * In p1 space must not be in shadow region.
        !           120:                 */
        !           121:                if (v < pcb.pcb_p1lr)
        !           122:                        goto oor;
        !           123:                addr = pcb.pcb_p1br+v;
        !           124:                break;
        !           125: 
        !           126:        case 0x00000000:
        !           127:                /*
        !           128:                 * In p0 space must not be off end of region.
        !           129:                 */
        !           130:                if (v >= pcb.pcb_p0lr)
        !           131:                        goto oor;
        !           132:                addr = pcb.pcb_p0br+v;
        !           133:                break;
        !           134:        oor:
        !           135:                errflg = "address out of segment";
        !           136:                return (-1);
        !           137:        }
        !           138:        /*
        !           139:         * For p0/p1 address, user-level page table should
        !           140:         * be in kernel vm.  Do second-level indirect by recursing.
        !           141:         */
        !           142:        if ((addr & 0x80000000) == 0) {
        !           143:                errflg = "bad p0br or p1br in pcb";
        !           144:                return (-1);
        !           145:        }
        !           146:        addr = vtophys(addr);
        !           147: simple:
        !           148:        /*
        !           149:         * Addr is now address of the pte of the page we
        !           150:         * are interested in; get the pte and paste up the
        !           151:         * physical address.
        !           152:         */
        !           153:        if (physrw(fcor, addr, (int *)&pte, 1) < 0) {
        !           154:                errflg = "page table botch";
        !           155:                return (-1);
        !           156:        }
        !           157:        /* SHOULD CHECK NOT I/O ADDRESS; NEED CPU TYPE! */
        !           158:        if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) {
        !           159:                errflg = "page not valid/reclaimable";
        !           160:                return (-1);
        !           161:        }
        !           162:        return (ptob(pte.pg_pfnum) + (oldaddr & PGOFSET));
        !           163: }
        !           164: 
        !           165: rwerr(space)
        !           166:        int space;
        !           167: {
        !           168: 
        !           169:        if (space & DSP)
        !           170:                errflg = "data address not found";
        !           171:        else
        !           172:                errflg = "text address not found";
        !           173: }
        !           174: 
        !           175: physrw(file, addr, aw, rd)
        !           176:        off_t addr;
        !           177:        int *aw, rd;
        !           178: {
        !           179: 
        !           180:        if (longseek(file,addr)==0 ||
        !           181:            (rd ? read(file,aw,sizeof(int)) : write(file,aw,sizeof(int))) < 1)
        !           182:                return (-1);
        !           183:        return (0);
        !           184: }
        !           185: 
        !           186: chkmap(addr,space)
        !           187:        REG L_INT       *addr;
        !           188:        REG INT         space;
        !           189: {
        !           190:        REG MAPPTR amap;
        !           191:        amap=((space&DSP?&datmap:&txtmap));
        !           192:        IF space&STAR ORF !within(*addr,amap->b1,amap->e1)
        !           193:        THEN IF within(*addr,amap->b2,amap->e2)
        !           194:             THEN *addr += (amap->f2)-(amap->b2);
        !           195:             ELSE rwerr(space); return(0);
        !           196:             FI
        !           197:        ELSE *addr += (amap->f1)-(amap->b1);
        !           198:        FI
        !           199:        return(1);
        !           200: }
        !           201: 
        !           202: within(addr,lbd,ubd)
        !           203:     u_int addr, lbd, ubd; { return(addr>=lbd && addr<ubd); }
        !           204: 
        !           205: longseek(f, a)
        !           206:     off_t a; { return(lseek(f, a, 0) != -1); }

unix.superglobalmegacorp.com

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