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