V8/usr/src/cmd/adb/access.c

Compare this file to the similar file:
Show the results in this format:

/*
 * access the files:
 * read or write data from some address in some space
 */

#include "defs.h"
#include "regs.h"
#include <sys/param.h>

/*
 * routines to get/put various types
 */

TLONG
lget(addr, space)
ADDR addr;
int space;
{
	TLONG x;

	if ((space & SPTYPE) == NOSP)
		return (wtol(dot));
	if (fget(addr, space, (char *)&x, sizeof(x)) == 0)
		return (0);
	return (x);
}

TSHORT
sget(addr, space)
ADDR addr;
int space;
{
	TSHORT x;

	if ((space & SPTYPE) == NOSP)
		return (wtos(dot));
	if (fget(addr, space, (char *)&x, sizeof(x)) == 0)
		return (0);
	return (x);
}

TCHAR
cget(addr, space)
ADDR addr;
int space;
{
	TCHAR x;

	if ((space & SPTYPE) == NOSP)
		return (wtoc(dot));
	if (fget(addr, space, (char *)&x, sizeof(x)) == 0)
		return (0);
	return (x);
}

TADDR
aget(addr, space)
ADDR addr;
int space;
{
	TADDR x;

	if ((space & SPTYPE) == NOSP)
		return (wtoa(dot));
	if (fget(addr, space, (char *)&x, sizeof(x)) == 0)
		return (0);
	return (x);
}

lput(addr, space, v)
ADDR addr;
int space;
TLONG v;
{

	return (fput(addr, space, (char *)&v, sizeof(v)));
}

sput(addr, space, v)
ADDR addr;
int space;
TSHORT v;
{

	return (fput(addr, space, (char *)&v, sizeof(v)));
}

cput(addr, space, v)
ADDR addr;
int space;
TCHAR v;
{

	return (fput(addr, space, (char *)&v, sizeof(v)));
}

aput(addr, space, v)
ADDR addr;
int space;
TADDR v;
{

	return (fput(addr, space, (char *)&v, sizeof(v)));
}

/*
 * the real io code
 */

int
fget(addr, space, buf, size)
ADDR addr;
register int space;
char *buf;
int size;
{
	int fd;
	off_t off;
	ADDR oa;
	ADDR regaddr();
	off_t lseek();

	if ((space & SPTYPE) == NOSP) {
		memset(buf, 0, size);
		memcpy(buf, (char *)&dot, size < sizeof(dot) ? sizeof(dot) : size);
		return (1);
	}
	if (space & SYMF)
		fd = fsym;
	else
		fd = fcor;
	oa = addr;
	if ((space & SPTYPE) == REGSP) {
		if (space & SYMF) {
			errflg = "registers in corefile only";
			return (0);
		}
		if ((addr = regaddr(addr)) == 0)
			return (intrget(oa, buf, size));
		space &=~ SPTYPE;
		space |= DATASP;
	}
	if (reloc(addr, space, &off) == 0)
		return (0);
	if (lseek(fd, off, 0) == -1
	||  read(fd, buf, size) != size) {
		if ((space & SPTYPE) == INSTSP)
			errflg = "can't read text";
		else
			errflg = "can't read data";
		return (0);
	}
	return (1);
}

int
fput(addr, space, buf, size)
ADDR addr;
register int space;
char *buf;
int size;
{
	int fd;
	off_t off;
	ADDR oa;
	ADDR regaddr();
	off_t lseek();

	if ((space & SPTYPE) == NOSP)
		return (0);
	if (wtflag == 0
	&&  !((space & SYMF) == 0 && pid))
		error("not in write mode");
	if (space & SYMF)
		fd = fsym;
	else
		fd = fcor;
	oa = addr;
	if ((space & SPTYPE) == REGSP) {
		if (space & SYMF) {
			errflg = "registers in corefile only";
			return (0);
		}
		if ((addr = regaddr(addr)) == 0)
			return (intrput(oa, buf, size));
		space &=~ SPTYPE;
		space |= DATASP;
	}
	if (reloc(addr, space, &off) == 0)
		return (0);
	if (lseek(fd, off, 0) == -1
	||  write(fd, buf, size) != size) {
		if ((space & SPTYPE) == INSTSP)
			errflg = "can't write text";
		else
			errflg = "can't write data";
		return (0);
	}
	return (1);
}

/*
 * register address hacks
 * if the register allegedly has an address (e.g. we're knee deep in
 * stack frames), return that
 * otherwise do fake io to our internal copies of registers
 * awful
 */

static ADDR
regaddr(reg)
register ADDR reg;
{
	extern ADDR raddr[];

	reg /= sizeof(TREG);
	if (MINREG <= reg && reg <= MAXREG)
		return (raddr[reg - MINREG]);
	return (0);
}

static int
intrget(reg, buf, size)
ADDR reg;
char *buf;
{
	register char *p, *q;
	register int n;
	register int rnum;
	TREG r;
	extern int roffs[];

	for (p = buf, n = size; n > 0; n--)
		*p++ = 0;
	rnum = reg / sizeof(TREG);
	if (rnum < MINREG)
		return (0);
	p = buf;
	while (rnum <= MAXREG && size > 0) {
		r = rget(roffs[rnum - MINREG]);
		for (q = (char *)&r, n = sizeof(TREG); n > 0; n--)
			*p++ = *q++;
		size -= sizeof(TREG);
		rnum++;
	}
	return (size <= 0);
}

static int
intrput(reg, buf, size)
ADDR reg;
char *buf;
{
	register char *p, *q;
	register int n;
	register int rnum;
	TREG r;
	extern int roffs[];

	rnum = reg / sizeof(TREG);
	if (rnum < MINREG)
		return (0);
	p = buf;
	while (rnum <= MAXREG && size > 0) {
		r = rget(roffs[rnum - MINREG]);
		for (q = (char *)&r, n = sizeof(TREG); n > 0 && size > 0; n--, size--)
			*q++ = *p++;
		rput(roffs[rnum - MINREG], r);
		rnum++;
	}
	return (size <= 0);
}

/*
 * turn address to file offset
 * returns nonzero if ok
 */


int
reloc(addr, space, offp)
ADDR addr;
register int space;
off_t *offp;
{
	register struct map *mp;

	for (mp = (space & SYMF) ? symmap : cormap; mp->flag & MPINUSE; mp++)
		if ((space & SPTYPE) == (mp->sp & SPTYPE)
		&&  mp->b <= addr && addr < mp->e) {
			addr += mp->f - mp->b;
			if ((space & (SYMF|RAWADDR)) == 0)
				if (kmap(&addr, space) == 0)
					return (0);
			*offp = addr;
			return (1);
		}
	/*
	 * if we wanted instruction space and didn't find it,
	 * try data space now
	 */
	if ((space & SPTYPE) == INSTSP) {
		space &=~ SPTYPE;
		space |= DATASP;
		for (mp = (space & SYMF) ? symmap : cormap; mp->flag & MPINUSE; mp++)
			if ((space & SPTYPE) == (mp->sp & SPTYPE)
			&&  mp->b <= addr && addr < mp->e) {
				addr += mp->f - mp->b;
				if ((space & (SYMF|RAWADDR)) == 0)
					if (kmap(&addr, space) == 0)
						return (0);
				*offp = addr;
				return (1);
			}
	}
	if (space & SYMF)
		errflg = "text address not found";
	else
		errflg = "data address not found";
	return (0);
}