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

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)access.c   4.8 10/13/84";
        !             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 ?
        !            67:                    (rd ? PT_READ_D : PT_WRITE_D) :
        !            68:                    (rd ? PT_READ_I : PT_WRITE_I));
        !            69: 
        !            70:                w = ptrace(pmode, pid, addr, value);
        !            71:                if (errno)
        !            72:                        rwerr(space);
        !            73:                return (w);
        !            74:        }
        !            75:        w = 0;
        !            76:        if (mode==WT && wtflag==0)
        !            77:                error("not in write mode");
        !            78:        if (!chkmap(&addr, space))
        !            79:                return (0);
        !            80:        file = (space&DSP) ? datmap.ufd : txtmap.ufd;
        !            81:        if (kernel && space == DSP) {
        !            82:                addr = vtophys(addr);
        !            83:                if (addr < 0)
        !            84:                        return (0);
        !            85:        }
        !            86:        if (physrw(file, addr, rd ? &w : &value, rd) < 0)
        !            87:                rwerr(space);
        !            88:        return (w);
        !            89: }
        !            90: 
        !            91: /*
        !            92:  * When looking at kernel data space through /dev/mem or
        !            93:  * with a core file, do virtual memory mapping.
        !            94:  */
        !            95: vtophys(addr)
        !            96:        off_t addr;
        !            97: {
        !            98:        int oldaddr = addr;
        !            99:        int v;
        !           100:        struct pte pte;
        !           101: 
        !           102:        addr &= ~0xc0000000;
        !           103:        v = btop(addr);
        !           104:        switch (oldaddr&0xc0000000) {
        !           105: 
        !           106:        case 0xc0000000:
        !           107:        case 0x80000000:
        !           108:                /*
        !           109:                 * In system space get system pte.  If
        !           110:                 * valid or reclaimable then physical address
        !           111:                 * is combination of its page number and the page
        !           112:                 * offset of the original address.
        !           113:                 */
        !           114:                if (v >= slr)
        !           115:                        goto oor;
        !           116:                addr = ((long)(sbr+v)) &~ 0x80000000;
        !           117:                goto simple;
        !           118: 
        !           119:        case 0x40000000:
        !           120:                /*
        !           121:                 * In p1 space must not be in shadow region.
        !           122:                 */
        !           123:                if (v < pcb.pcb_p1lr)
        !           124:                        goto oor;
        !           125:                addr = pcb.pcb_p1br+v;
        !           126:                break;
        !           127: 
        !           128:        case 0x00000000:
        !           129:                /*
        !           130:                 * In p0 space must not be off end of region.
        !           131:                 */
        !           132:                if (v >= pcb.pcb_p0lr)
        !           133:                        goto oor;
        !           134:                addr = pcb.pcb_p0br+v;
        !           135:                break;
        !           136:        oor:
        !           137:                errflg = "address out of segment";
        !           138:                return (-1);
        !           139:        }
        !           140:        /*
        !           141:         * For p0/p1 address, user-level page table should
        !           142:         * be in kernel vm.  Do second-level indirect by recursing.
        !           143:         */
        !           144:        if ((addr & 0x80000000) == 0) {
        !           145:                errflg = "bad p0br or p1br in pcb";
        !           146:                return (-1);
        !           147:        }
        !           148:        addr = vtophys(addr);
        !           149: simple:
        !           150:        /*
        !           151:         * Addr is now address of the pte of the page we
        !           152:         * are interested in; get the pte and paste up the
        !           153:         * physical address.
        !           154:         */
        !           155:        if (physrw(fcor, addr, (int *)&pte, 1) < 0) {
        !           156:                errflg = "page table botch";
        !           157:                return (-1);
        !           158:        }
        !           159:        /* SHOULD CHECK NOT I/O ADDRESS; NEED CPU TYPE! */
        !           160:        if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) {
        !           161:                errflg = "page not valid/reclaimable";
        !           162:                return (-1);
        !           163:        }
        !           164:        return (ptob(pte.pg_pfnum) + (oldaddr & PGOFSET));
        !           165: }
        !           166: 
        !           167: rwerr(space)
        !           168:        int space;
        !           169: {
        !           170: 
        !           171:        if (space & DSP)
        !           172:                errflg = "data address not found";
        !           173:        else
        !           174:                errflg = "text address not found";
        !           175: }
        !           176: 
        !           177: physrw(file, addr, aw, rd)
        !           178:        off_t addr;
        !           179:        int *aw, rd;
        !           180: {
        !           181: 
        !           182:        if (longseek(file,addr)==0 ||
        !           183:            (rd ? read(file,aw,sizeof(int)) : write(file,aw,sizeof(int))) < 1)
        !           184:                return (-1);
        !           185:        return (0);
        !           186: }
        !           187: 
        !           188: chkmap(addr,space)
        !           189:        REG L_INT       *addr;
        !           190:        REG INT         space;
        !           191: {
        !           192:        REG MAPPTR amap;
        !           193:        amap=((space&DSP?&datmap:&txtmap));
        !           194:        IF space&STAR ORF !within(*addr,amap->b1,amap->e1)
        !           195:        THEN IF within(*addr,amap->b2,amap->e2)
        !           196:             THEN *addr += (amap->f2)-(amap->b2);
        !           197:             ELSE rwerr(space); return(0);
        !           198:             FI
        !           199:        ELSE *addr += (amap->f1)-(amap->b1);
        !           200:        FI
        !           201:        return(1);
        !           202: }
        !           203: 
        !           204: within(addr,lbd,ubd)
        !           205:     u_int addr, lbd, ubd; { return(addr>=lbd && addr<ubd); }
        !           206: 
        !           207: longseek(f, a)
        !           208:     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.