* Adb: access data in file/process address space.
* The routines in this file access referenced data using
* the maps to access files, ptrace to access subprocesses,
* or the system page tables when debugging the kernel,
* to translate virtual to physical addresses.
static char sccsid
[] = "@(#) 4.6 %G%";
* Primitives: put a value in a space, get a value from a space
* and get a word or byte not returning if an error occurred.
off_t addr
; { (void) access(WT
, addr
, space
, value
); }
off_t addr
; { return (access(RD
, addr
, space
, 0)); };
off_t addr
; { u_int w
= get(addr
, space
); chkerr(); return(w
); }
off_t addr
; { return(chkget(addr
, space
) & LOBYTE
); }
* Read/write according to mode at address addr in i/d space.
* Value is quantity to be written, if write.
* This routine decides whether to get the data from the subprocess
* address space with ptrace, or to get it from the files being
* When the kernel is being debugged with the -k flag we interpret
* the system page tables for data space, mapping p0 and p1 addresses
* relative to the ``current'' process (as specified by its p_addr in
* <p) and mapping system space addresses through the system page tables.
access(mode
, addr
, space
, value
)
int pmode
= (space
&DSP
?(rd
?RDUSER
:WDUSER
):(rd
?RIUSER
:WIUSER
));
w
= ptrace(pmode
, pid
, addr
, value
);
if (mode
==WT
&& wtflag
==0)
error("not in write mode");
if (!chkmap(&addr
, space
))
file
= (space
&DSP
) ? datmap
.ufd
: txtmap
.ufd
;
if (kernel
&& space
== DSP
) {
if (physrw(file
, addr
, rd
? &w
: &value
, rd
) < 0)
* When looking at kernel data space through /dev/mem or
* with a core file, do virtual memory mapping.
switch (oldaddr
&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.
addr
= ((long)(sbr
+v
)) &~ 0x80000000;
* In p1 space must not be in shadow region.
* In p0 space must not be off end of region.
errflg
= "address out of segment";
* For p0/p1 address, user-level page table should
* be in kernel vm. Do second-level indirect by recursing.
if ((addr
& 0x80000000) == 0) {
errflg
= "bad p0br or p1br in pcb";
* Addr is now address of the pte of the page we
* are interested in; get the pte and paste up the
if (physrw(fcor
, addr
, (int *)&pte
, 1) < 0) {
errflg
= "page table botch";
/* SHOULD CHECK NOT I/O ADDRESS; NEED CPU TYPE! */
if (pte
.pg_v
== 0 && (pte
.pg_fod
|| pte
.pg_pfnum
== 0)) {
errflg
= "page not valid/reclaimable";
return (ptob(pte
.pg_pfnum
) + (oldaddr
& PGOFSET
));
errflg
= "data address not found";
errflg
= "text address not found";
physrw(file
, addr
, aw
, rd
)
if (longseek(file
,addr
)==0 ||
(rd
? read(file
,aw
,sizeof(int)) : write(file
,aw
,sizeof(int))) < 1)
amap
=((space
&DSP
?&datmap
:&txtmap
));
IF space
&STAR ORF
!within(*addr
,amap
->b1
,amap
->e1
)
THEN IF
within(*addr
,amap
->b2
,amap
->e2
)
THEN
*addr
+= (amap
->f2
)-(amap
->b2
);
ELSE
rwerr(space
); return(0);
ELSE
*addr
+= (amap
->f1
)-(amap
->b1
);
u_int addr
, lbd
, ubd
; { return(addr
>=lbd
&& addr
<ubd
); }
off_t a
; { return(lseek(f
, a
, 0) != -1); }