|
|
researchv8 Dan Cross
/*
* 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);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.