121627Sdist /*
238105Sbostic * Copyright (c) 1983 The Regents of the University of California.
338105Sbostic * All rights reserved.
438105Sbostic *
542683Sbostic * %sccs.include.redist.c%
621627Sdist */
79661Slinton
821627Sdist #ifndef lint
9*44669Strent static char sccsid[] = "@(#)coredump.c 5.6 (Berkeley) 06/29/90";
1038105Sbostic #endif /* not lint */
119661Slinton
129661Slinton /*
139661Slinton * Deal with the core dump anachronism.
149661Slinton */
159661Slinton
169661Slinton #include "defs.h"
179661Slinton #include "coredump.h"
189661Slinton #include "machine.h"
199661Slinton #include "object.h"
209661Slinton #include "main.h"
219661Slinton #include <a.out.h>
229661Slinton
239661Slinton #ifndef public
249661Slinton #define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s))
259661Slinton
269661Slinton #include "machine.h"
279661Slinton #endif
289661Slinton
299661Slinton typedef struct {
309661Slinton Address begin;
319661Slinton Address end;
329661Slinton Address seekaddr;
339661Slinton } Map;
349661Slinton
359661Slinton private Map datamap, stkmap;
369661Slinton private File objfile;
379661Slinton private struct exec hdr;
389661Slinton
coredump_getkerinfo()3918215Slinton public coredump_getkerinfo ()
4018215Slinton {
4118215Slinton Symbol s;
4218215Slinton
4318215Slinton s = lookup(identname("Sysmap", true));
4418215Slinton if (s == nil) {
4518215Slinton panic("can't find 'Sysmap'");
469661Slinton }
4718215Slinton sbr = (struct pte *) (s->symvalue.offset);
4818215Slinton s = lookup(identname("Syssize", true));
4918215Slinton if (s == nil) {
5018215Slinton panic("can't find 'Syssize'");
5118215Slinton }
5218215Slinton slr = (integer) (s->symvalue.offset);
5318215Slinton printf("sbr %lx slr %lx\n", sbr, slr);
5418215Slinton s = lookup(identname("masterpaddr", true));
5518215Slinton if (s == nil) {
5618215Slinton panic("can't find 'masterpaddr'");
5718215Slinton }
5833313Sdonn fseek(
5933313Sdonn corefile,
6033313Sdonn datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin,
6133313Sdonn 0
6233313Sdonn );
6318215Slinton get(corefile, masterpcbb);
6426334Ssam masterpcbb = (masterpcbb&PG_PFNUM)*NBPG;
6518215Slinton getpcb();
6618215Slinton }
6718215Slinton
6818215Slinton /*
6918215Slinton * Read the user area information from the core dump.
7018215Slinton */
719661Slinton
coredump_xreadin(mask,reg,signo)7218215Slinton public coredump_xreadin(mask, reg, signo)
7318215Slinton int *mask;
7418215Slinton Word reg[];
7526334Ssam short *signo;
7618215Slinton {
7718215Slinton register struct user *up;
7818215Slinton register Word *savreg;
7918215Slinton union {
8018215Slinton struct user u;
8118215Slinton char dummy[ctob(UPAGES)];
8218215Slinton } ustruct;
8318215Slinton Symbol s;
8418215Slinton
8518215Slinton objfile = fopen(objname, "r");
8618215Slinton if (objfile == nil) {
8718215Slinton fatal("can't read \"%s\"", objname);
889661Slinton }
8918215Slinton get(objfile, hdr);
9018215Slinton if (vaddrs) {
9118215Slinton datamap.begin = 0;
9218215Slinton datamap.end = 0xffffffff;
9318215Slinton stkmap.begin = 0xffffffff;
9418215Slinton stkmap.end = 0xffffffff;
9518215Slinton } else {
9618215Slinton up = &(ustruct.u);
9718215Slinton fread(up, ctob(UPAGES), 1, corefile);
9833313Sdonn # if vax || tahoe
9933313Sdonn savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]);
10033313Sdonn # else ifdef mc68000
10133313Sdonn savreg = (Word *) (
10233313Sdonn &ustruct.dummy[ctob(UPAGES) - 10] - (NREG * sizeof(Word))
10333313Sdonn );
10433313Sdonn # endif
10533313Sdonn # ifdef IRIS
10633313Sdonn *mask = savreg[RPS];
10733313Sdonn # else
10833313Sdonn *mask = savreg[PS];
10933313Sdonn # endif
11018215Slinton copyregs(savreg, reg);
111*44669Strent *signo = up->u_sig;
11218215Slinton datamap.seekaddr = ctob(UPAGES);
11326334Ssam stkmap.begin = USRSTACK - ctob(up->u_ssize);
11426334Ssam stkmap.end = USRSTACK;
11518215Slinton stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize);
11618215Slinton switch (hdr.a_magic) {
11718215Slinton case OMAGIC:
11833313Sdonn datamap.begin = CODESTART;
11933313Sdonn datamap.end = CODESTART + ctob(up->u_tsize) + ctob(up->u_dsize);
12018215Slinton break;
12118215Slinton
12218215Slinton case NMAGIC:
12318215Slinton case ZMAGIC:
12433313Sdonn datamap.begin = (Address)
12533313Sdonn ptob(btop(ctob(up->u_tsize) - 1) + 1) + CODESTART;
12618215Slinton datamap.end = datamap.begin + ctob(up->u_dsize);
12718215Slinton break;
12818215Slinton
12918215Slinton default:
13018215Slinton fatal("bad magic number 0x%x", hdr.a_magic);
13118215Slinton }
13218215Slinton #ifdef UXMAG
13318215Slinton /*
13418215Slinton * Core dump not from this object file?
13518215Slinton */
13618215Slinton if (hdr.a_magic != 0 and up->u_exdata.ux_mag != 0 and
13718215Slinton hdr.a_magic != up->u_exdata.ux_mag) {
13818215Slinton warning("core dump ignored");
13918215Slinton coredump = false;
14018215Slinton fclose(corefile);
14118215Slinton fclose(objfile);
14218215Slinton start(nil, nil, nil);
14318215Slinton }
14418215Slinton #endif
14518215Slinton }
1469661Slinton }
1479661Slinton
coredump_close()1489661Slinton public coredump_close()
1499661Slinton {
1509661Slinton fclose(objfile);
1519661Slinton }
1529661Slinton
coredump_readtext(buff,addr,nbytes)1539661Slinton public coredump_readtext(buff, addr, nbytes)
1549661Slinton char *buff;
1559661Slinton Address addr;
1569661Slinton int nbytes;
1579661Slinton {
15818215Slinton if (hdr.a_magic == OMAGIC or vaddrs) {
1599661Slinton coredump_readdata(buff, addr, nbytes);
1609661Slinton } else {
16133313Sdonn fseek(objfile, N_TXTOFF(hdr) + addr - CODESTART, 0);
1629661Slinton fread(buff, nbytes, sizeof(Byte), objfile);
1639661Slinton }
1649661Slinton }
1659661Slinton
coredump_readdata(buff,addr,nbytes)1669661Slinton public coredump_readdata(buff, addr, nbytes)
1679661Slinton char *buff;
1689661Slinton Address addr;
1699661Slinton int nbytes;
1709661Slinton {
17118215Slinton Address a;
17218215Slinton
17318215Slinton a = addr;
17418215Slinton if (a < datamap.begin) {
17516608Ssam if (hdr.a_magic == OMAGIC) {
17618215Slinton error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin);
17716608Ssam } else {
17818215Slinton coredump_readtext(buff, a, nbytes);
17916608Ssam }
18018215Slinton } else if (a > stkmap.end) {
18118215Slinton error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end);
1829661Slinton } else {
18318215Slinton if (vaddrs) {
18418215Slinton vreadfromfile(corefile, a, buff, nbytes);
18518215Slinton } else {
18618215Slinton readfromfile(corefile, a, buff, nbytes);
18718215Slinton }
1889661Slinton }
1899661Slinton }
19018215Slinton
19118215Slinton /*
19218215Slinton * Read a block of data from a memory image, mapping virtual addresses.
19318215Slinton * Have to watch out for page boundaries.
19418215Slinton */
19518215Slinton
vreadfromfile(corefile,v,buff,nbytes)19618215Slinton private vreadfromfile (corefile, v, buff, nbytes)
19718215Slinton File corefile;
19818215Slinton Address v;
19918215Slinton char *buff;
20018215Slinton integer nbytes;
20118215Slinton {
20218215Slinton Address a;
20318215Slinton integer i, remainder, pagesize;
20418215Slinton char *bufp;
20518215Slinton
20618215Slinton a = v;
20718215Slinton pagesize = (integer) ptob(1);
20818215Slinton remainder = pagesize - (a mod pagesize);
20918215Slinton if (remainder >= nbytes) {
21018215Slinton readfromfile(corefile, vmap(a), buff, nbytes);
21118215Slinton } else {
21218215Slinton readfromfile(corefile, vmap(a), buff, remainder);
21318215Slinton a += remainder;
21418215Slinton i = nbytes - remainder;
21518215Slinton bufp = buff + remainder;
21618215Slinton while (i > pagesize) {
21718215Slinton readfromfile(corefile, vmap(a), bufp, pagesize);
21818215Slinton a += pagesize;
21918215Slinton bufp += pagesize;
22018215Slinton i -= pagesize;
22118215Slinton }
22218215Slinton readfromfile(corefile, vmap(a), bufp, i);
22318215Slinton }
22418215Slinton }
22518215Slinton
readfromfile(f,a,buff,nbytes)22618215Slinton private readfromfile (f, a, buff, nbytes)
22718215Slinton File f;
22818215Slinton Address a;
22918215Slinton char *buff;
23018215Slinton integer nbytes;
23118215Slinton {
23218215Slinton integer fileaddr;
23318215Slinton
23418215Slinton if (a < stkmap.begin) {
23518215Slinton fileaddr = datamap.seekaddr + a - datamap.begin;
23618215Slinton } else {
23718215Slinton fileaddr = stkmap.seekaddr + a - stkmap.begin;
23818215Slinton }
23918215Slinton fseek(f, fileaddr, 0);
24018215Slinton fread(buff, nbytes, sizeof(Byte), f);
24118215Slinton }
242