X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/6eadceb10933fec7fd1ad9f54aea34968daabb6e..5cd863dd553ace3f0a747b56eefa7c68348164f0:/usr/src/old/adb/adb.vax/access.c diff --git a/usr/src/old/adb/adb.vax/access.c b/usr/src/old/adb/adb.vax/access.c index e865c5c1de..3d99b93844 100644 --- a/usr/src/old/adb/adb.vax/access.c +++ b/usr/src/old/adb/adb.vax/access.c @@ -1,18 +1,18 @@ -# +#ifndef lint +static char sccsid[] = "@(#)access.c 4.8 %G%"; +#endif /* + * Adb: access data in file/process address space. * - * UNIX debugger - * + * The routines in this file access referenced data using + * the maps to access files, ptrace to access subprocesses, + * or the system page tables when debugging the kernel, + * to translate virtual to physical addresses. */ -#define dprintf if (0) printf - #include "defs.h" -static char sccsid[] = "@(#)access.c 4.2 %G%"; -MSG ODDADR; -MSG BADDAT; -MSG BADTXT; + MAP txtmap; MAP datmap; INT wtflag; @@ -21,181 +21,188 @@ INT errno; INT pid; -/* file handling and access routines */ +/* + * Primitives: put a value in a space, get a value from a space + * and get a word or byte not returning if an error occurred. + */ +put(addr, space, value) + off_t addr; { (void) access(WT, addr, space, value); } -put(adr,space,value) -#ifndef EDDT -L_INT adr; -{ - access(WT,adr,space,value); -} -#else - L_INT *adr; {*adr=value;} -#endif +u_int +get(addr, space) + off_t addr; { return (access(RD, addr, space, 0)); }; -POS get(adr, space) -#ifndef EDDT -L_INT adr; -{ - return(access(RD,adr,space,0)); -} -#else - L_INT *adr; {return(*adr);} -#endif +u_int +chkget(addr, space) + off_t addr; { u_int w = get(addr, space); chkerr(); return(w); } -POS chkget(n, space) -L_INT n; -{ -#ifndef vax - REG INT w; -#else - REG L_INT w; -#endif - - w = get(n, space); - chkerr(); - return(w); -} +u_int +bchkget(addr, space) + off_t addr; { return(chkget(addr, space) & LOBYTE); } -POS bchkget(n, space) -L_INT n; +/* + * Read/write according to mode at address addr in i/d space. + * Value is quantity to be written, if write. + * + * This routine decides whether to get the data from the subprocess + * address space with ptrace, or to get it from the files being + * debugged. + * + * When the kernel is being debugged with the -k flag we interpret + * the system page tables for data space, mapping p0 and p1 addresses + * relative to the ``current'' process (as specified by its p_addr in + *
>8)&LOBYTE | (w1<<8);
- FI
-#endif
- IF errno
- THEN errflg = (space&DSP ? BADDAT : BADTXT);
- FI
- return(w);
- FI
- w = 0;
- IF mode==WT ANDF wtflag==0
- THEN error("not in write mode");
- FI
- IF !chkmap(&adr,space)
- THEN return(0);
- FI
- file=(space&DSP?datmap.ufd:txtmap.ufd);
- IF kernel && space == DSP THEN
- int oadr = adr;
- int v;
- adr &= ~0x80000000;
- IF oadr&0x80000000 THEN /* system space */
- v = btop(adr);
- dprintf("system addr %X, v %X\n", adr, v);
- IF v >= slr THEN errflg="bad system space addr"; return (0); FI
- adr = vtoa(file, adr);
- IF adr == -1 THEN
- errflg="sys page table page not valid"; return (0); FI
- ELIF adr&0x40000000 THEN /* p1 space */
- v = btop(adr&~0x40000000);
- dprintf("p1 addr %X, v %X, p1br %X p1lr %X\n", adr, v,
- pcb.pcb_p1br, pcb.pcb_p1lr);
- IF v < pcb.pcb_p1lr THEN
- errflg="bad p1 space addr"; return (0); FI
- adr = vtoa(file, pcb.pcb_p1br+v);
- IF adr == -1 THEN
- errflg="p1 page table page not valid"; return (0); FI
- goto get;
- ELSE /* p0 space */
- dprintf("p0 addr %X, v %X, p0br %X p0lr %X\n", adr,
- v, pcb.pcb_p0br, pcb.pcb_p0lr);
- IF v >= pcb.pcb_p0lr THEN
- errflg="bad p0 space addr"; return (0); FI
- adr = vtoa(file, pcb.pcb_p0br+v);
- IF adr == -1 THEN
- errflg="p0 page table page not valid"; return (0); FI
-get:
- dprintf("addr for pt page %X\n", adr);
- IF physrw(file, adr, &adr, 1) < 0 THEN
- errflg = "page tables botched"; return (0); FI
- dprintf("user pte value %X\n", adr);
- IF (adr & PG_V) == 0 &&
- ((adr & PG_FOD) || (adr & PG_PFNUM) == 0) THEN
- errflg = "user page not resident"; return (0);
- FI
- adr = ((adr & 0xfffff) << 9) | (oadr & 0x1ff);
- FI
- FI
- IF physrw(file, adr, &w, rd) < 0 THEN
- errflg=(space&DSP?BADDAT:BADTXT);
- FI
- return(w);
+ addr &= ~0xc0000000;
+ v = btop(addr);
+ switch (oldaddr&0xc0000000) {
+
+ case 0xc0000000:
+ case 0x80000000:
+ /*
+ * In system space get system pte. If
+ * valid or reclaimable then physical address
+ * is combination of its page number and the page
+ * offset of the original address.
+ */
+ if (v >= slr)
+ goto oor;
+ addr = ((long)(sbr+v)) &~ 0x80000000;
+ goto simple;
+
+ case 0x40000000:
+ /*
+ * In p1 space must not be in shadow region.
+ */
+ if (v < pcb.pcb_p1lr)
+ goto oor;
+ addr = pcb.pcb_p1br+v;
+ break;
+
+ case 0x00000000:
+ /*
+ * In p0 space must not be off end of region.
+ */
+ if (v >= pcb.pcb_p0lr)
+ goto oor;
+ addr = pcb.pcb_p0br+v;
+ break;
+ oor:
+ errflg = "address out of segment";
+ return (-1);
+ }
+ /*
+ * For p0/p1 address, user-level page table should
+ * be in kernel vm. Do second-level indirect by recursing.
+ */
+ if ((addr & 0x80000000) == 0) {
+ errflg = "bad p0br or p1br in pcb";
+ return (-1);
+ }
+ addr = vtophys(addr);
+simple:
+ /*
+ * Addr is now address of the pte of the page we
+ * are interested in; get the pte and paste up the
+ * physical address.
+ */
+ if (physrw(fcor, addr, (int *)&pte, 1) < 0) {
+ errflg = "page table botch";
+ return (-1);
+ }
+ /* SHOULD CHECK NOT I/O ADDRESS; NEED CPU TYPE! */
+ if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) {
+ errflg = "page not valid/reclaimable";
+ return (-1);
+ }
+ return (ptob(pte.pg_pfnum) + (oldaddr & PGOFSET));
}
-#endif
-physrw(file, adr, aw, rd)
-int *aw;
+rwerr(space)
+ int space;
{
- dprintf("physrw(%X) %s to %X\n", adr, rd ? "read" : "write", aw);
- IF longseek(file,adr)==0 ORF
- (rd ? read(file,aw,sizeof(int)) : write(file,aw,sizeof(int))) < 1
- THEN return (-1);
- FI
- return (0);
+ if (space & DSP)
+ errflg = "data address not found";
+ else
+ errflg = "text address not found";
}
-vtoa(file, va)
-unsigned long va;
+physrw(file, addr, aw, rd)
+ off_t addr;
+ int *aw, rd;
{
- struct pte pte;
- physrw(file, ((long)(sbr + btop(va&0x7fffffff)))&~0x80000000, &pte, 1);
- dprintf("vtoa got pte %X\n", pte);
- if (pte.pg_v || (pte.pg_fod == 0 && pte.pg_pfnum))
- return (ptob(pte.pg_pfnum) + (va & PGOFSET));
- errflg = "page not resident";
- return (-1);
+ if (longseek(file,addr)==0 ||
+ (rd ? read(file,aw,sizeof(int)) : write(file,aw,sizeof(int))) < 1)
+ return (-1);
+ return (0);
}
-
-chkmap(adr,space)
- REG L_INT *adr;
+
+chkmap(addr,space)
+ REG L_INT *addr;
REG INT space;
{
REG MAPPTR amap;
amap=((space&DSP?&datmap:&txtmap));
- IF space&STAR ORF !within(*adr,amap->b1,amap->e1)
- THEN IF within(*adr,amap->b2,amap->e2)
- THEN *adr += (amap->f2)-(amap->b2);
- ELSE errflg=(space&DSP?BADDAT:BADTXT); return(0);
+ IF space&STAR ORF !within(*addr,amap->b1,amap->e1)
+ THEN IF within(*addr,amap->b2,amap->e2)
+ THEN *addr += (amap->f2)-(amap->b2);
+ ELSE rwerr(space); return(0);
FI
- ELSE *adr += (amap->f1)-(amap->b1);
+ ELSE *addr += (amap->f1)-(amap->b1);
FI
return(1);
}
-within(adr,lbd,ubd)
-POS adr, lbd, ubd;
-{
- return(adr>=lbd && adr