BSD 4_1c_2 release
[unix-history] / usr / src / ucb / dbx / coredump.c
/* Copyright (c) 1982 Regents of the University of California */
static char sccsid[] = "@(#)coredump.c 1.4 1/25/83";
/*
* Deal with the core dump anachronism.
*
* If I understood this code, I'd try to make it readable.
*/
#include "defs.h"
#include "coredump.h"
#include "machine.h"
#include "object.h"
#include "main.h"
#include <sys/param.h>
#include <sys/dir.h>
#include <machine/psl.h>
#include <machine/pte.h>
#include <sys/user.h>
#include <sys/vm.h>
#include <machine/reg.h>
#include <a.out.h>
#ifndef public
#define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s))
#include "machine.h"
#endif
#define MAXSTKADDR (0x80000000 - ctob(UPAGES)) /* highest stack address */
typedef struct {
Address begin;
Address end;
Address seekaddr;
} Map;
private Map datamap, stkmap;
private File objfile;
private struct exec hdr;
/*
* Read the user area information from the core dump.
*/
public coredump_xreadin(mask, reg, signo)
int *mask;
Word reg[];
int *signo;
{
register struct user *up;
register Word *savreg;
union {
struct user u;
char dummy[ctob(UPAGES)];
} ustruct;
objfile = fopen(objname, "r");
if (objfile == nil) {
fatal("can't read \"%s\"", objname);
}
get(objfile, hdr);
up = &(ustruct.u);
fread(up, ctob(UPAGES), 1, corefile);
savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]);
*mask = savreg[PS];
reg[0] = savreg[R0];
reg[1] = savreg[R1];
reg[2] = savreg[R2];
reg[3] = savreg[R3];
reg[4] = savreg[R4];
reg[5] = savreg[R5];
reg[6] = savreg[R6];
reg[7] = savreg[R7];
reg[8] = savreg[R8];
reg[9] = savreg[R9];
reg[10] = savreg[R10];
reg[11] = savreg[R11];
reg[ARGP] = savreg[AP];
reg[FRP] = savreg[FP];
reg[STKP] = savreg[SP];
reg[PROGCTR] = savreg[PC];
*signo = up->u_arg[0];
datamap.seekaddr = ctob(UPAGES);
stkmap.begin = MAXSTKADDR - ctob(up->u_ssize);
stkmap.end = MAXSTKADDR;
stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize);
switch (hdr.a_magic) {
case OMAGIC:
datamap.begin = 0;
datamap.end = ctob(up->u_tsize) + ctob(up->u_dsize);
break;
case NMAGIC:
case ZMAGIC:
datamap.begin = (Address) ptob(btop(ctob(up->u_tsize) - 1) + 1);
datamap.end = datamap.begin + ctob(up->u_dsize);
break;
default:
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");
coredump = false;
fclose(corefile);
fclose(objfile);
start(nil, nil, nil);
}
}
public coredump_close()
{
fclose(objfile);
}
public coredump_readtext(buff, addr, nbytes)
char *buff;
Address addr;
int nbytes;
{
if (hdr.a_magic == OMAGIC) {
coredump_readdata(buff, addr, nbytes);
} else {
fseek(objfile, N_TXTOFF(hdr) + addr, 0);
fread(buff, nbytes, sizeof(Byte), objfile);
}
}
public coredump_readdata(buff, addr, nbytes)
char *buff;
Address addr;
int nbytes;
{
if (addr < datamap.begin) {
error("data address 0x%x too low (lb = 0x%x)", addr, datamap.begin);
} else if (addr > stkmap.end) {
error("data address 0x%x too high (ub = 0x%x)", addr, stkmap.end);
} else if (addr < stkmap.begin) {
fseek(corefile, datamap.seekaddr + addr - datamap.begin, 0);
fread(buff, nbytes, sizeof(Byte), corefile);
} else {
fseek(corefile, stkmap.seekaddr + addr - stkmap.begin, 0);
fread(buff, nbytes, sizeof(Byte), corefile);
}
}