xref: /csrg-svn/old/dbx/coredump.c (revision 38105)
121627Sdist /*
2*38105Sbostic  * Copyright (c) 1983 The Regents of the University of California.
3*38105Sbostic  * All rights reserved.
4*38105Sbostic  *
5*38105Sbostic  * Redistribution and use in source and binary forms are permitted
6*38105Sbostic  * provided that the above copyright notice and this paragraph are
7*38105Sbostic  * duplicated in all such forms and that any documentation,
8*38105Sbostic  * advertising materials, and other materials related to such
9*38105Sbostic  * distribution and use acknowledge that the software was developed
10*38105Sbostic  * by the University of California, Berkeley.  The name of the
11*38105Sbostic  * University may not be used to endorse or promote products derived
12*38105Sbostic  * from this software without specific prior written permission.
13*38105Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*38105Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*38105Sbostic  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1621627Sdist  */
179661Slinton 
1821627Sdist #ifndef lint
19*38105Sbostic static char sccsid[] = "@(#)coredump.c	5.4 (Berkeley) 05/23/89";
20*38105Sbostic #endif /* not lint */
219661Slinton 
229661Slinton /*
239661Slinton  * Deal with the core dump anachronism.
249661Slinton  */
259661Slinton 
269661Slinton #include "defs.h"
279661Slinton #include "coredump.h"
289661Slinton #include "machine.h"
299661Slinton #include "object.h"
309661Slinton #include "main.h"
319661Slinton #include <a.out.h>
329661Slinton 
339661Slinton #ifndef public
349661Slinton #define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s))
359661Slinton 
369661Slinton #include "machine.h"
379661Slinton #endif
389661Slinton 
399661Slinton typedef struct {
409661Slinton     Address begin;
419661Slinton     Address end;
429661Slinton     Address seekaddr;
439661Slinton } Map;
449661Slinton 
459661Slinton private Map datamap, stkmap;
469661Slinton private File objfile;
479661Slinton private struct exec hdr;
489661Slinton 
4918215Slinton public coredump_getkerinfo ()
5018215Slinton {
5118215Slinton     Symbol s;
5218215Slinton 
5318215Slinton     s = lookup(identname("Sysmap", true));
5418215Slinton     if (s == nil) {
5518215Slinton 	panic("can't find 'Sysmap'");
569661Slinton     }
5718215Slinton     sbr = (struct pte *) (s->symvalue.offset);
5818215Slinton     s = lookup(identname("Syssize", true));
5918215Slinton     if (s == nil) {
6018215Slinton 	panic("can't find 'Syssize'");
6118215Slinton     }
6218215Slinton     slr = (integer) (s->symvalue.offset);
6318215Slinton     printf("sbr %lx slr %lx\n", sbr, slr);
6418215Slinton     s = lookup(identname("masterpaddr", true));
6518215Slinton     if (s == nil) {
6618215Slinton 	panic("can't find 'masterpaddr'");
6718215Slinton     }
6833313Sdonn     fseek(
6933313Sdonn 	corefile,
7033313Sdonn 	datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin,
7133313Sdonn 	0
7233313Sdonn     );
7318215Slinton     get(corefile, masterpcbb);
7426334Ssam     masterpcbb = (masterpcbb&PG_PFNUM)*NBPG;
7518215Slinton     getpcb();
7618215Slinton }
7718215Slinton 
7818215Slinton /*
7918215Slinton  * Read the user area information from the core dump.
8018215Slinton  */
819661Slinton 
8218215Slinton public coredump_xreadin(mask, reg, signo)
8318215Slinton int *mask;
8418215Slinton Word reg[];
8526334Ssam short *signo;
8618215Slinton {
8718215Slinton     register struct user *up;
8818215Slinton     register Word *savreg;
8918215Slinton     union {
9018215Slinton 	struct user u;
9118215Slinton 	char dummy[ctob(UPAGES)];
9218215Slinton     } ustruct;
9318215Slinton     Symbol s;
9418215Slinton 
9518215Slinton     objfile = fopen(objname, "r");
9618215Slinton     if (objfile == nil) {
9718215Slinton 	fatal("can't read \"%s\"", objname);
989661Slinton     }
9918215Slinton     get(objfile, hdr);
10018215Slinton     if (vaddrs) {
10118215Slinton 	datamap.begin = 0;
10218215Slinton 	datamap.end = 0xffffffff;
10318215Slinton 	stkmap.begin = 0xffffffff;
10418215Slinton 	stkmap.end = 0xffffffff;
10518215Slinton     } else {
10618215Slinton 	up = &(ustruct.u);
10718215Slinton 	fread(up, ctob(UPAGES), 1, corefile);
10833313Sdonn #	if vax || tahoe
10933313Sdonn 	    savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]);
11033313Sdonn #	else ifdef mc68000
11133313Sdonn 	    savreg = (Word *) (
11233313Sdonn 		&ustruct.dummy[ctob(UPAGES) - 10] - (NREG * sizeof(Word))
11333313Sdonn 	    );
11433313Sdonn #	endif
11533313Sdonn #       ifdef IRIS
11633313Sdonn 	    *mask = savreg[RPS];
11733313Sdonn #       else
11833313Sdonn 	    *mask = savreg[PS];
11933313Sdonn #       endif
12018215Slinton 	copyregs(savreg, reg);
12118215Slinton 	*signo = up->u_arg[0];
12218215Slinton 	datamap.seekaddr = ctob(UPAGES);
12326334Ssam 	stkmap.begin = USRSTACK - ctob(up->u_ssize);
12426334Ssam 	stkmap.end = USRSTACK;
12518215Slinton 	stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize);
12618215Slinton 	switch (hdr.a_magic) {
12718215Slinton 	    case OMAGIC:
12833313Sdonn 		datamap.begin = CODESTART;
12933313Sdonn 		datamap.end = CODESTART + ctob(up->u_tsize) + ctob(up->u_dsize);
13018215Slinton 		break;
13118215Slinton 
13218215Slinton 	    case NMAGIC:
13318215Slinton 	    case ZMAGIC:
13433313Sdonn 		datamap.begin = (Address)
13533313Sdonn 		    ptob(btop(ctob(up->u_tsize) - 1) + 1) + CODESTART;
13618215Slinton 		datamap.end = datamap.begin + ctob(up->u_dsize);
13718215Slinton 		break;
13818215Slinton 
13918215Slinton 	    default:
14018215Slinton 		fatal("bad magic number 0x%x", hdr.a_magic);
14118215Slinton 	}
14218215Slinton #ifdef UXMAG
14318215Slinton 	/*
14418215Slinton 	 * Core dump not from this object file?
14518215Slinton 	 */
14618215Slinton 	if (hdr.a_magic != 0 and up->u_exdata.ux_mag  != 0 and
14718215Slinton 	  hdr.a_magic != up->u_exdata.ux_mag) {
14818215Slinton 	    warning("core dump ignored");
14918215Slinton 	    coredump = false;
15018215Slinton 	    fclose(corefile);
15118215Slinton 	    fclose(objfile);
15218215Slinton 	    start(nil, nil, nil);
15318215Slinton 	}
15418215Slinton #endif
15518215Slinton     }
1569661Slinton }
1579661Slinton 
1589661Slinton public coredump_close()
1599661Slinton {
1609661Slinton     fclose(objfile);
1619661Slinton }
1629661Slinton 
1639661Slinton public coredump_readtext(buff, addr, nbytes)
1649661Slinton char *buff;
1659661Slinton Address addr;
1669661Slinton int nbytes;
1679661Slinton {
16818215Slinton     if (hdr.a_magic == OMAGIC or vaddrs) {
1699661Slinton 	coredump_readdata(buff, addr, nbytes);
1709661Slinton     } else {
17133313Sdonn 	fseek(objfile, N_TXTOFF(hdr) + addr - CODESTART, 0);
1729661Slinton 	fread(buff, nbytes, sizeof(Byte), objfile);
1739661Slinton     }
1749661Slinton }
1759661Slinton 
1769661Slinton public coredump_readdata(buff, addr, nbytes)
1779661Slinton char *buff;
1789661Slinton Address addr;
1799661Slinton int nbytes;
1809661Slinton {
18118215Slinton     Address a;
18218215Slinton 
18318215Slinton     a = addr;
18418215Slinton     if (a < datamap.begin) {
18516608Ssam 	if (hdr.a_magic == OMAGIC) {
18618215Slinton 	    error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin);
18716608Ssam 	} else {
18818215Slinton 	    coredump_readtext(buff, a, nbytes);
18916608Ssam 	}
19018215Slinton     } else if (a > stkmap.end) {
19118215Slinton 	error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end);
1929661Slinton     } else {
19318215Slinton 	if (vaddrs) {
19418215Slinton 	    vreadfromfile(corefile, a, buff, nbytes);
19518215Slinton 	} else {
19618215Slinton 	    readfromfile(corefile, a, buff, nbytes);
19718215Slinton 	}
1989661Slinton     }
1999661Slinton }
20018215Slinton 
20118215Slinton /*
20218215Slinton  * Read a block of data from a memory image, mapping virtual addresses.
20318215Slinton  * Have to watch out for page boundaries.
20418215Slinton  */
20518215Slinton 
20618215Slinton private vreadfromfile (corefile, v, buff, nbytes)
20718215Slinton File corefile;
20818215Slinton Address v;
20918215Slinton char *buff;
21018215Slinton integer nbytes;
21118215Slinton {
21218215Slinton     Address a;
21318215Slinton     integer i, remainder, pagesize;
21418215Slinton     char *bufp;
21518215Slinton 
21618215Slinton     a = v;
21718215Slinton     pagesize = (integer) ptob(1);
21818215Slinton     remainder = pagesize - (a mod pagesize);
21918215Slinton     if (remainder >= nbytes) {
22018215Slinton 	readfromfile(corefile, vmap(a), buff, nbytes);
22118215Slinton     } else {
22218215Slinton 	readfromfile(corefile, vmap(a), buff, remainder);
22318215Slinton 	a += remainder;
22418215Slinton 	i = nbytes - remainder;
22518215Slinton 	bufp = buff + remainder;
22618215Slinton 	while (i > pagesize) {
22718215Slinton 	    readfromfile(corefile, vmap(a), bufp, pagesize);
22818215Slinton 	    a += pagesize;
22918215Slinton 	    bufp += pagesize;
23018215Slinton 	    i -= pagesize;
23118215Slinton 	}
23218215Slinton 	readfromfile(corefile, vmap(a), bufp, i);
23318215Slinton     }
23418215Slinton }
23518215Slinton 
23618215Slinton private readfromfile (f, a, buff, nbytes)
23718215Slinton File f;
23818215Slinton Address a;
23918215Slinton char *buff;
24018215Slinton integer nbytes;
24118215Slinton {
24218215Slinton     integer fileaddr;
24318215Slinton 
24418215Slinton     if (a < stkmap.begin) {
24518215Slinton 	fileaddr = datamap.seekaddr + a - datamap.begin;
24618215Slinton     } else {
24718215Slinton 	fileaddr = stkmap.seekaddr + a - stkmap.begin;
24818215Slinton     }
24918215Slinton     fseek(f, fileaddr, 0);
25018215Slinton     fread(buff, nbytes, sizeof(Byte), f);
25118215Slinton }
252