File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / bin / cdb / 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

#include <sys/types.h>
#include <sys/timeb.h>
struct timeb tp;
long	times_check[8000];
long	times_ndx;

static char sccsid[] = "@(#)access.c	2.7";

/* most of this file is MACHINE DEPENDENT !!
 * EVERY line should be examined for potential problems, including
 *      byte sex        (had any lately??)
 *      regsiter vs int size problems
 *      word, long, byte alignment problems
 *      Other random droppings from the Bird of Happiness
 *
 *      Many of these are fixable by modifying various definitions
 *      in pas.h, cdb.h, and particularly macdefs.h
 *
 *	WARNING: As of 3-7-83, it is the assumption of virtually
 *	all of these routines that the byte sex of the debugger's
 *	machine is the same as that of the debuggee's machine.
 *	I currently do not have a fix for it, but this is clearly
 *	the file which needs to deal with this problem.
 */

#include <errno.h>
#ifndef REGULUS

#ifdef BSD42
#include <machine/reg.h>
#else
#include <sys/reg.h>
#endif

#endif
#include "macdefs.h"
#include "cdb.h"

export int      vpid;   /* process ID of child */
export int	vimap;  /* selects alternate mapping - sorta kludgey */
export ADRT     vsp, vpc, vfp, vap;
export REGT     *v_ar0; /* value stored in u.u_ar0 - see InitAll */

#ifdef SUN
int vrgOffset[] = {
	R0,  R1,  R2,  R3,
	R4,  R5,  R6,  R7,
	AR0, AR1, AR2, AR3,
	AR4, AR5, AR6, AR7,
	PC,  PS,  AR6, SP	/* AR6 is FP */
};
#endif
#ifdef REGULUS
#define cbUserRegs 18*4
int vrgOffset[] = {
	0,  1,  2,  3,  4,  5,  6,  7,
	8,  9, 10, 11, 12, 13, 14, 15,
	16, 17, 14, 15		/* last two are sp and fp */
};
#endif
#ifdef ONYX
int vrgOffset[] = {
	R0,  R1,  R2,  R3,
	R4,  R5,  R6,  R7,
	R8,  R9,  R10, R11,
	R12, R13, R14, R15,
	SP,  PC,  R14, FCW      /* frame pointer is R14 on Onyx */
};
#endif
#ifdef TAHOE
int vrgOffset[] = {
	R0,  R1,  R2,  R3,
	R4,  R5,  R6,  R7,
	R8,  R9,  R10, R11,
	R12, FP,  SP,  PC,
	PS,
};
#endif

#ifdef VAX
int vrgOffset[] = {
	R0,  R1,  R2,  R3,
	R4,  R5,  R6,  R7,
	R8,  R9,  R10, R11,
	R12, R13, AP,  FP,
	SP,  PS,  PC,
};
#endif


/* G E T   U S E R */

export REGT GetUser(adr)
ADRT    adr;
{
	int         val;

	if (vpid != pidNil) {
		val = ptrace(ptReadUser, vpid, adr, 0);
		if (val == -1 AND errno == EIO) {
			if (FOdd(adr))
				UError("Attempt to write to ODD address");
#ifdef REGULUS
			Panic("Failed on ptReadUser - %#lo, %ld", adr, val);
#else
			Panic("Failed on ptReadUser - %#o, %d", adr, val);
#endif
		} /* if */
	} 
	else if (vfnCore != fnNil) {
		if (lseek(vfnCore, lengthen(adr), 0) < 0L)
			UError("address not found");
		if (read(vfnCore, &val, CBPOINT) < 1)
			UError("Cannot read that location");
	} 
	else {
		UError("No child process AND no core file");
	} /* if */
	return(val);
} /* GetUser */


/* P U T   U S E R */

export void PutUser(adr, val)
ADRT    adr;
REGT    val;
{
	int         i;

	if (vpid != pidNil) {
		i = ptrace(ptWriteUser, vpid, adr, val);
		if (i == -1 AND errno == EIO) {
			if (FOdd(adr))
				UError("Attempt to write to ODD address");
#ifdef REGULUS
			Panic("Failed on ptWriteUser - %#lo, %ld", adr, val);
#else
			Panic("Failed on ptWriteUser - %#o, %d", adr, val);
#endif
		} /* if */
	} 
	else if (vfnCore != fnNil) {
		if (lseek(vfnCore, lengthen(adr), 0) < 0L)
			UError("address not found");
		if (write(vfnCore, &val, CBPOINT) < 1 )
			UError("Cannot write that location");
	} 
	else {
		UError("No child process AND no core file");
	} /* if */
} /* PutUser */


/* G E T   R E G  */

export REGT GetReg(reg)
int   reg;
{
	ADRT         adr;

	adr = (ADRT)(v_ar0 + vrgOffset[reg]);
	return(GetUser(adr));
} /* GetReg */


/* P U T   R E G  */

export void PutReg(reg, val)
int	reg;
REGT	val;
{
	ADRT	adr;

	/* keep our globals up to date */
	switch (reg) {
	case upc:	
		vpc = val;	
		break;
	case ufp:	
		vfp = val;	
		break;
	case usp:	
		vsp = val;	
		break;
#ifdef VAX
	case uap:	
		vap = val;	
		break;
#endif
	} /* switch */
	adr = (ADRT)(v_ar0 + vrgOffset[reg]);
	PutUser(adr, val);
} /* PutReg */


/* S A V E   R E G S */

export void SaveRegs(regs)
REGT     *regs;
{
#ifndef REGULUS
	int       i;
	for (i = 0; i < uregMax; i++)
		regs[i] = GetReg(i);
#else
	if (trace(ptWriteUser, vpid, cbUserRegs, regs, v_ar0) < 0)
		Panic("Bad register");
#endif
	regs[upc] = vpc;    /* we do this because it may have been up-dated */
} /* SaveRegs */


/* R E S T O R E   R E G S */

export void RestoreRegs(regs)
REGT     *regs;
{
#ifndef REGULUS
	int       i;

	for (i = 0; i< uregMax; i++)
		PutReg(i, regs[i]);
#else
	if (trace(ptWriteUser, vpid, cbUserRegs, regs, v_ar0) < 0)
		Panic("Bad register");
#endif
	vpc = regs[upc];
	vsp = regs[usp];
	vfp = regs[ufp];
#ifndef VAX
	vap = vfp;
#else
	vap = regs[uap];
#endif
} /* RestoreRegs */


/* P U T   S T A T E */

export void PutState()
{
#ifdef VAX
	PutReg(uap, vap);
#endif
	PutReg(ufp, vfp);
	PutReg(usp, vsp);
	PutReg(upc, vpc);
} /* PutState */


/* G E T   S T A T E */

export void GetState()
{
	vfp = GetReg(ufp);
	vsp = GetReg(usp);
	vpc = GetReg(upc);
#ifndef VAX
	vap = vfp;
#else
	vap = GetReg(uap);
	if (vpc > 0x70000000) {
		vpc -= 0x7fff0000;	/* BSD 4.X sticks this crud on top of pc */
		vpc--;	/* back up to problem statement */
	} /* if */
#endif
} /* GetState */


/* G E T   W O R D */

export int GetWord(adr, space)
ADRT	adr;
int	space;
{
	return(Access(accRead, adr, space, 0));
} /* GetWord */


/* G E T   B Y T E */

export int GetByte(adr, space)
ADRT	adr;
int	space;
{
	STUFFU	stuff;

#ifdef EVENBYTES
	ADRT        adrOnWord;

	adrOnWord = adr & ~1;
#ifdef M68000
	stuff.lng = Access(accRead, adrOnWord, space, 0);
	return((adrOnWord == adr) ? stuff.chars.chHiHi : stuff.chars.chHiLo);
#else
	stuff.shorts.shortLo = Access(accRead, adrOnWord, space, 0);
	return((adrOnWord == adr) ? stuff.chars.chLoHi : stuff.chars.chLoLo);
#endif
#endif
#ifdef TAHOE
	stuff.lng = Access(accRead, adr, space, 0);
	return(stuff.chars.chHiHi);
#endif
#ifdef VAX
	stuff.lng = Access(accRead, adr, space, 0);
	return(stuff.chars.chLoLo);
#endif
} /* GetByte */


/* P U T   W O R D */

export void PutWord(adr, space, val)
ADRT    adr;
int     space, val;
{
	Access(accWrite, adr, space, val);
} /* PutWord */


/* P U T   B Y T E */

export void PutByte(adr, space, val)
ADRT    adr;
int     space, val;
{
	STUFFU      stuff;

#ifdef EVENBYTES
	ADRT        adrOnWord;

	adrOnWord = adr & ~1;
#ifdef M68000
	stuff.lng = Access(accRead, adrOnWord, space, 0);
	if (adrOnWord == adr)
		stuff.chars.chHiHi = val;
	else
		stuff.chars.chHiLo = val;
	Access(accWrite, adrOnWord, space, stuff.lng);
#else
	stuff.shorts.shortLo = Access(accRead, adrOnWord, space, 0);
	if (adrOnWord == adr)
		stuff.chars.chLoHi = val;
	else
		stuff.chars.chLoLo = val;
	Access(accWrite, adrOnWord, space, stuff.shorts.shortLo);
#endif
#endif
#ifdef TAHOE
	stuff.lng = Access(accRead, adr, space, 0);
	stuff.chars.chHiHi = val;
	Access(accWrite, adr, space, stuff.lng);
#endif
#ifdef VAX
	stuff.lng = Access(accRead, adr, space, 0);
	stuff.chars.chLoLo = val;
	Access(accWrite, adr, space, stuff.lng);
#endif
} /* PutByte */


/* Get Block and PutBlock could be sped up by knowing about where
 * word boundaries are and such, but it doesn't seem worth it at the
 * moment.  Maybe later.
 */

/* G E T   B L O C K */

export void GetBlock(adr, space, adrValue, cb)
ADRT    adr, adrValue;
int	space, cb;
{
#ifndef REGULUS
	char        *pCh;

	pCh = (char *) adrValue;	/* point to receiving area */
	while (cb--)
		*pCh++ = GetByte(adr++, space);
#else
	if (trace(ptReadD, vpid, cb, adrValue, adr) < 0)
		UError("address not found");
#endif
} /* GetBlock */


/* P U T   B L O C K */

export void PutBlock(adr, space, adrValue, cb)
ADRT    adr, adrValue;
int	space, cb;
{
#ifndef REGULUS
	char        *pCh;

	pCh = (char *) adrValue;	/* point to sending area */
	while (cb--)
		PutByte(adr++, space, *pCh++);
#else
	if (trace(ptWriteD, vpid, cb, adrValue, adr) < 0)
		UError("address not found");
#endif
} /* PutBlock */


/* A C C E S S */

export int Access(accRequest, adrIn, space, value)
int	accRequest, space, value;
ADRT    adrIn;
{
	int         ret, val, pt, fn;
	long        adrLong;
	FLAGT       fRead;

	fRead = (accRequest == accRead);
	if (vpid != pidNil) {      /* we have a live process */
		if (space == spaceData)
			pt = (fRead) ? ptReadD : ptWriteD;  /* data space */
		else
			pt = (fRead) ? ptReadI : ptWriteI;  /* instruction space */

		val = ptrace(pt, vpid, adrIn, value);
		if (errno != 0)
			UError("bad access");
		return(val);
	} /* if */

	/* we do NOT have a process, see if we have a core file to get it from */

	adrLong = adrIn;
	val = 0;
	if (!FAdrGood(&adrLong, space))
		return(0);
	fn = (space == spaceData) ? vmapCore.fn : vmapText.fn;
	if (fn == fnNil)
		UError("No core file");
	if (lseek(fn, adrLong, 0) < 0L)
		UError("address not found");
	ret = (fRead) ? read(fn, &val, CBINT) 
		: write(fn, &value, CBINT);
	if (ret != CBINT)
		UError("Cannot %s that location", (fRead) ? "read" : "write");
	return(val);
} /* Access */


/* F   A D R   G O O D */

export int FAdrGood(padrLong, space)
long    *padrLong;
int	space;
{
	pMAPR       map;

#define FWithin(x, lbd, ubd) ((x>=lbd) && (x<ubd))

	map = (space == spaceData) ? &vmapCore : &vmapText;
	if ((vimap == 0)
	    AND (FWithin(*padrLong, map->b1, map->e1))) {
		*padrLong += (map->f1)-(map->b1);
	} 
	else if (FWithin(*padrLong, map->b2, map->e2)) {
		*padrLong += (map->f2) - (map->b2);
	} 
	else {
		UError("No such address");
	} /* if */
	return(true);
} /* FAdrGood */


/* M O V E   B Y T E S */

export void MoveBytes(adrDest, adrSrc, cb)
ADRT	adrDest, adrSrc;
int	cb;
{
	char	*dest, *src;

	dest = (char *)adrDest;
	src = (char *)adrSrc;

	/*
	     * this routine will do overlapping moves to the right or left.
	     */
	if (dest < src) {
		while (cb--)
			*dest++ = *src++;
	} 
	else {
		dest += cb;
		src += cb;
		while (cb--)
			*--dest = *--src;
	} /* if */
} /* MoveBytes */


/* L O N G   R O U N D */

export long LongRound(a, b)
long    a, b;
{
	return( ((a+b-1)/b)*b );
} /* LongRound */


/* D O   M A P */

export void DoMap()
{
	int		i;
	char        ch;
	long        *pl, tempLong;
	TKE         tk;
	pTYR        ty;

	tk = TkNext();
	if (tk != tkNil) {
		ch = vsbTok[0];
		if ( (tk != tkStr)
		    OR (ch != 't' AND ch != 'c') ) {
			UError("usage: M (t|c) number; number; .. (up to 6 numbers)");
		} 
		else {
			pl = (ch == 't') ? &(vmapText.b1) : &(vmapCore.b1);
		} /* if */
		tk = TkNext();
		for (i=0; i<6; i++, pl++) {
			if (tk == tkSemi) {
				tk = TkNext();
				continue;       /* field separator */
			} /* if */
			tempLong = GetExpr(&ty, tk);
			tk = vtk;
			if (tk == tkSemi)
				tk = TkNext();  /* eat the semicolon */
			if (ty == tyNil)
				break;
			*pl = tempLong;
		} /* for */
	} /* if */

	printf("Object file (%s):\n", vsbSymfile);
	printf(" %10s", SbFAdr(vmapText.b1, false));
	printf(" %10s", SbFAdr(vmapText.e1, false));
	printf(" %10s\n", SbFAdr(vmapText.f1, false));
	printf(" %10s", SbFAdr(vmapText.b2, false));
	printf(" %10s", SbFAdr(vmapText.e2, false));
	printf(" %10s\n", SbFAdr(vmapText.f2, false));
	printf("Core file (%s):\n", vsbCorefile);
	printf(" %10s", SbFAdr(vmapCore.b1, false));
	printf(" %10s", SbFAdr(vmapCore.e1, false));
	printf(" %10s\n", SbFAdr(vmapCore.f1, false));
	printf(" %10s", SbFAdr(vmapCore.b2, false));
	printf(" %10s", SbFAdr(vmapCore.e2, false));
	printf(" %10s\n", SbFAdr(vmapCore.f2, false));
} /* DoMap */

unix.superglobalmegacorp.com

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