File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / bin / adb / access.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (6 years, 11 months ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
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);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.