|
|
Power 6/32 Unix version 1.2b
/*
*
* UNIX debugger
*
*/
#include "defs.h"
MSG BADDAT;
MSG BADTXT;
MSG ADDOOS;
MSG BADBR;
MSG BADPT;
MSG BADPAGE;
MAP txtmap;
MAP datmap;
INT wtflag;
STRING errflg;
INT errno;
L_INT pid;
/* file handling and access routines */
put(adr,space,value)
#ifndef EDDT
L_INT adr;
{
access(WT,adr,space,value);
}
#else
L_INT *adr; {*adr=value;}
#endif
POS get(adr, space)
#ifndef EDDT
L_INT adr;
{
return(access(RD,adr,space,0));
}
#else
L_INT *adr; {return(*adr);}
#endif
POS chkget(n, space)
L_INT n;
{
REG w;
w = get(n, space);
chkerr();
return(w);
}
POS bchkget(n, space)
L_INT n;
{
return(byte(chkget(n, space)));
}
/*
* When the kernel is being debugged with the -k flag we interpret
* the system page tables for data space, mapping p0 and p2 addresses
* relative to the 'current' process (as specified by its p_addr in <p)
* and mapping system space addresses through the system page tables.
*/
#ifndef EDDT
access(mode,adr,space,value)
L_INT adr;
ADDR value;
{
REG pmode,rd,file;
ADDR w;
rd = mode==RD;
IF space == NSP THEN return(0); FI
IF pid /* tracing on? */
THEN
pmode = (space&DSP?(rd?RDUSER:WDUSER):(rd?RIUSER:WIUSER));
w = ptrace(pmode, pid, adr, value);
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 ANDF space == DSP
THEN
adr = vtophys(adr);
IF (adr < 0)
THEN return(0);
FI
FI
IF physrw(file,adr,rd ? &w : &value,rd) < 0
THEN errflg=(space&DSP?BADDAT:BADTXT);
FI
return(w);
}
#endif
/*
* When looking at kernel data space through /dev/mem or
* with a core file, do virtual memory mapping.
*/
vtophys(addr)
off_t addr;
{
REG v, oldaddr = addr;
STRUCT pte pte;
addr &= ~0xc0000000;
v = btop(addr);
switch (oldaddr&0xc0000000) {
case 0xc0000000:
/*
* 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
THEN goto oor;
FI
addr = ((long)(sbr + v)) & ~0xc0000000;
goto simple;
default:
return(-1);
oor:
errflg = ADDOOS;
return(-1);
}
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
THEN
errflg = BADPT;
return(-1);
FI
IF pte.pg_v == 0 ANDF (pte.pg_fod ORF pte.pg_pfnum == 0)
THEN
errflg = BADPAGE;
return(-1);
FI
return((ADDR)ptob(pte.pg_pfnum) + (oldaddr & PGOFSET));
}
physrw(file,addr,aw,rd)
off_t addr;
REG *aw, rd;
{
IF longseek(file,addr)==0 ORF
(rd ? read(file,aw,sizeof(int)) : write(file,aw,sizeof(int))) < 1
THEN return(-1);
FI
return(0);
}
chkmap(adr,space)
REG POS *adr;
REG 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);
FI
ELSE *adr += (amap->f1)-(amap->b1);
FI
return(1);
}
within(adr,lbd,ubd)
POS adr, lbd, ubd;
{
return(adr>=lbd && adr<ubd);
}
longseek(f, a)
L_INT 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.