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=lbd && addr