/* Copyright (c) 1982 Regents of the University of California */
static char sccsid
[] = "@(#)coredump.c 1.7 (Berkeley) %G%";
static char rcsid
[] = "$Header: coredump.c,v 1.5 84/12/26 10:38:56 linton Exp $";
* Deal with the core dump anachronism.
#define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s))
#define MAXSTKADDR (0x80000000 - ctob(UPAGES)) /* highest stack address */
private Map datamap
, stkmap
;
* Special variables for debugging the kernel.
private integer masterpcbb
;
fseek(corefile
, masterpcbb
& ~0x80000000, 0);
pcb
.pcb_p0lr
&= ~AST_CLR
;
printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",
pcb
.pcb_p0br
, pcb
.pcb_p0lr
, pcb
.pcb_p1br
, pcb
.pcb_p1lr
setreg(ARGP
, pcb
.pcb_ap
);
setreg(STKP
, pcb
.pcb_ksp
);
setreg(PROGCTR
, pcb
.pcb_pc
);
public coredump_getkerinfo ()
s
= lookup(identname("Sysmap", true));
panic("can't find 'Sysmap'");
sbr
= (struct pte
*) (s
->symvalue
.offset
);
s
= lookup(identname("Syssize", true));
panic("can't find 'Syssize'");
slr
= (integer
) (s
->symvalue
.offset
);
printf("sbr %lx slr %lx\n", sbr
, slr
);
s
= lookup(identname("masterpaddr", true));
panic("can't find 'masterpaddr'");
datamap
.seekaddr
+ s
->symvalue
.offset
&0x7fffffff - datamap
.begin
,
get(corefile
, masterpcbb
);
masterpcbb
= (masterpcbb
&PG_PFNUM
)*512;
private copyregs (savreg
, reg
)
reg
[PROGCTR
] = savreg
[PC
];
* Read the user area information from the core dump.
public coredump_xreadin(mask
, reg
, signo
)
register struct user
*up
;
char dummy
[ctob(UPAGES
)];
objfile
= fopen(objname
, "r");
fatal("can't read \"%s\"", objname
);
datamap
.end
= 0xffffffff;
stkmap
.begin
= 0xffffffff;
fread(up
, ctob(UPAGES
), 1, corefile
);
savreg
= (Word
*) &(ustruct
.dummy
[ctob(UPAGES
)]);
datamap
.seekaddr
= ctob(UPAGES
);
stkmap
.begin
= MAXSTKADDR
- ctob(up
->u_ssize
);
stkmap
.seekaddr
= datamap
.seekaddr
+ ctob(up
->u_dsize
);
datamap
.end
= ctob(up
->u_tsize
) + ctob(up
->u_dsize
);
datamap
.begin
= (Address
) ptob(btop(ctob(up
->u_tsize
) - 1) + 1);
datamap
.end
= datamap
.begin
+ ctob(up
->u_dsize
);
fatal("bad magic number 0x%x", hdr
.a_magic
);
* Core dump not from this object file?
if (hdr
.a_magic
!= 0 and up
->u_exdata
.ux_mag
!= 0 and
hdr
.a_magic
!= up
->u_exdata
.ux_mag
) {
warning("core dump ignored");
public coredump_readtext(buff
, addr
, nbytes
)
if (hdr
.a_magic
== OMAGIC
or vaddrs
) {
coredump_readdata(buff
, addr
, nbytes
);
fseek(objfile
, N_TXTOFF(hdr
) + addr
, 0);
fread(buff
, nbytes
, sizeof(Byte
), objfile
);
* Map a virtual address to a physical address.
private Address
vmap (addr
)
switch (addr
&0xc0000000) {
* In system space, so get system pte.
* If it is valid or reclaimable then the physical address
* is the combination of its page number and the page offset
* of the original address.
error("address %x out of segment", addr
);
r
= ((long) (sbr
+ v
)) & ~0x80000000;
* In p1 space, must not be in shadow region.
error("address %x out of segment", addr
);
r
= (Address
) (pcb
.pcb_p1br
+ v
);
* In p0 space, must not be off end of region.
error("address %x out of segment", addr
);
r
= (Address
) (pcb
.pcb_p0br
+ v
);
* For p0/p1 address, user-level page table should be in
* kernel virtual memory. Do second-level indirect by recursing.
if ((r
& 0x80000000) == 0) {
error("bad p0br or p1br in pcb");
* "r" is now the address of the pte of the page
* we are interested in; get the pte and paste up the physical address.
n
= fread(&pte
, sizeof(pte
), 1, corefile
);
error("page table botch (fread at %x returns %d)", r
, n
);
if (pte
.pg_v
== 0 and (pte
.pg_fod
!= 0 or pte
.pg_pfnum
== 0)) {
error("page no valid or reclamable");
return (addr
&PGOFSET
) + ((Address
) ptob(pte
.pg_pfnum
));
public coredump_readdata(buff
, addr
, nbytes
)
if (hdr
.a_magic
== OMAGIC
) {
error("[data address 0x%x too low (lb = 0x%x)]", a
, datamap
.begin
);
coredump_readtext(buff
, a
, nbytes
);
} else if (a
> stkmap
.end
) {
error("data address 0x%x too high (ub = 0x%x)", a
, stkmap
.end
);
vreadfromfile(corefile
, a
, buff
, nbytes
);
readfromfile(corefile
, a
, buff
, nbytes
);
* Read a block of data from a memory image, mapping virtual addresses.
* Have to watch out for page boundaries.
private vreadfromfile (corefile
, v
, buff
, nbytes
)
integer i
, remainder
, pagesize
;
pagesize
= (integer
) ptob(1);
remainder
= pagesize
- (a mod pagesize
);
if (remainder
>= nbytes
) {
readfromfile(corefile
, vmap(a
), buff
, nbytes
);
readfromfile(corefile
, vmap(a
), buff
, remainder
);
readfromfile(corefile
, vmap(a
), bufp
, pagesize
);
readfromfile(corefile
, vmap(a
), bufp
, i
);
private readfromfile (f
, a
, buff
, nbytes
)
fileaddr
= datamap
.seekaddr
+ a
- datamap
.begin
;
fileaddr
= stkmap
.seekaddr
+ a
- stkmap
.begin
;
fread(buff
, nbytes
, sizeof(Byte
), f
);