1 # 2 /* 3 * 4 * UNIX debugger 5 * 6 */ 7 8 #define dprintf if (0) printf 9 10 #include "defs.h" 11 static char sccsid[] = "@(#)access.c 4.2 05/14/81"; 12 13 MSG ODDADR; 14 MSG BADDAT; 15 MSG BADTXT; 16 MAP txtmap; 17 MAP datmap; 18 INT wtflag; 19 STRING errflg; 20 INT errno; 21 22 INT pid; 23 24 /* file handling and access routines */ 25 26 put(adr,space,value) 27 #ifndef EDDT 28 L_INT adr; 29 { 30 access(WT,adr,space,value); 31 } 32 #else 33 L_INT *adr; {*adr=value;} 34 #endif 35 36 POS get(adr, space) 37 #ifndef EDDT 38 L_INT adr; 39 { 40 return(access(RD,adr,space,0)); 41 } 42 #else 43 L_INT *adr; {return(*adr);} 44 #endif 45 46 POS chkget(n, space) 47 L_INT n; 48 { 49 #ifndef vax 50 REG INT w; 51 #else 52 REG L_INT w; 53 #endif 54 55 w = get(n, space); 56 chkerr(); 57 return(w); 58 } 59 60 POS bchkget(n, space) 61 L_INT n; 62 { 63 return(chkget(n, space) & LOBYTE); 64 } 65 66 #ifndef EDDT 67 access(mode,adr,space,value) 68 long adr; 69 { 70 INT pmode,rd,file; 71 ADDR w; 72 rd = mode==RD; 73 74 IF space == NSP THEN return(0); FI 75 76 IF pid /* tracing on? */ 77 THEN 78 #ifndef vax 79 IF adr&01 ANDF !rd THEN error(ODDADR); FI 80 #endif 81 pmode = (space&DSP?(rd?RDUSER:WDUSER):(rd?RIUSER:WIUSER)); 82 w = ptrace(pmode, pid, adr, value); 83 #ifndef vax 84 IF adr&01 85 THEN w1 = ptrace(pmode, pid, shorten(adr+1), value); 86 w = (w>>8)&LOBYTE | (w1<<8); 87 FI 88 #endif 89 IF errno 90 THEN errflg = (space&DSP ? BADDAT : BADTXT); 91 FI 92 return(w); 93 FI 94 w = 0; 95 IF mode==WT ANDF wtflag==0 96 THEN error("not in write mode"); 97 FI 98 IF !chkmap(&adr,space) 99 THEN return(0); 100 FI 101 file=(space&DSP?datmap.ufd:txtmap.ufd); 102 IF kernel && space == DSP THEN 103 int oadr = adr; 104 int v; 105 adr &= ~0x80000000; 106 IF oadr&0x80000000 THEN /* system space */ 107 v = btop(adr); 108 dprintf("system addr %X, v %X\n", adr, v); 109 IF v >= slr THEN errflg="bad system space addr"; return (0); FI 110 adr = vtoa(file, adr); 111 IF adr == -1 THEN 112 errflg="sys page table page not valid"; return (0); FI 113 ELIF adr&0x40000000 THEN /* p1 space */ 114 v = btop(adr&~0x40000000); 115 dprintf("p1 addr %X, v %X, p1br %X p1lr %X\n", adr, v, 116 pcb.pcb_p1br, pcb.pcb_p1lr); 117 IF v < pcb.pcb_p1lr THEN 118 errflg="bad p1 space addr"; return (0); FI 119 adr = vtoa(file, pcb.pcb_p1br+v); 120 IF adr == -1 THEN 121 errflg="p1 page table page not valid"; return (0); FI 122 goto get; 123 ELSE /* p0 space */ 124 dprintf("p0 addr %X, v %X, p0br %X p0lr %X\n", adr, 125 v, pcb.pcb_p0br, pcb.pcb_p0lr); 126 IF v >= pcb.pcb_p0lr THEN 127 errflg="bad p0 space addr"; return (0); FI 128 adr = vtoa(file, pcb.pcb_p0br+v); 129 IF adr == -1 THEN 130 errflg="p0 page table page not valid"; return (0); FI 131 get: 132 dprintf("addr for pt page %X\n", adr); 133 IF physrw(file, adr, &adr, 1) < 0 THEN 134 errflg = "page tables botched"; return (0); FI 135 dprintf("user pte value %X\n", adr); 136 IF (adr & PG_V) == 0 && 137 ((adr & PG_FOD) || (adr & PG_PFNUM) == 0) THEN 138 errflg = "user page not resident"; return (0); 139 FI 140 adr = ((adr & 0xfffff) << 9) | (oadr & 0x1ff); 141 FI 142 FI 143 IF physrw(file, adr, &w, rd) < 0 THEN 144 errflg=(space&DSP?BADDAT:BADTXT); 145 FI 146 return(w); 147 } 148 #endif 149 150 physrw(file, adr, aw, rd) 151 int *aw; 152 { 153 154 dprintf("physrw(%X) %s to %X\n", adr, rd ? "read" : "write", aw); 155 IF longseek(file,adr)==0 ORF 156 (rd ? read(file,aw,sizeof(int)) : write(file,aw,sizeof(int))) < 1 157 THEN return (-1); 158 FI 159 return (0); 160 } 161 162 vtoa(file, va) 163 unsigned long va; 164 { 165 struct pte pte; 166 167 physrw(file, ((long)(sbr + btop(va&0x7fffffff)))&~0x80000000, &pte, 1); 168 dprintf("vtoa got pte %X\n", pte); 169 if (pte.pg_v || (pte.pg_fod == 0 && pte.pg_pfnum)) 170 return (ptob(pte.pg_pfnum) + (va & PGOFSET)); 171 errflg = "page not resident"; 172 return (-1); 173 } 174 175 chkmap(adr,space) 176 REG L_INT *adr; 177 REG INT space; 178 { 179 REG MAPPTR amap; 180 amap=((space&DSP?&datmap:&txtmap)); 181 IF space&STAR ORF !within(*adr,amap->b1,amap->e1) 182 THEN IF within(*adr,amap->b2,amap->e2) 183 THEN *adr += (amap->f2)-(amap->b2); 184 ELSE errflg=(space&DSP?BADDAT:BADTXT); return(0); 185 FI 186 ELSE *adr += (amap->f1)-(amap->b1); 187 FI 188 return(1); 189 } 190 191 within(adr,lbd,ubd) 192 POS adr, lbd, ubd; 193 { 194 return(adr>=lbd && adr<ubd); 195 } 196 197 longseek(f, a) 198 L_INT a; 199 { 200 return(lseek(f,a,0) != -1); 201 } 202