1 /* 2 * Copyright (c) 1983 Regents of the University of California. 3 * All rights reserved. The Berkeley software License Agreement 4 * specifies the terms and conditions for redistribution. 5 */ 6 7 #ifndef lint 8 static char sccsid[] = "@(#)coredump.c 5.3 (Berkeley) 01/12/88"; 9 #endif not lint 10 11 static char rcsid[] = "$Header: coredump.c,v 1.4 87/04/15 03:25:22 donn Exp $"; 12 13 /* 14 * Deal with the core dump anachronism. 15 */ 16 17 #include "defs.h" 18 #include "coredump.h" 19 #include "machine.h" 20 #include "object.h" 21 #include "main.h" 22 #include <a.out.h> 23 24 #ifndef public 25 #define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s)) 26 27 #include "machine.h" 28 #endif 29 30 typedef struct { 31 Address begin; 32 Address end; 33 Address seekaddr; 34 } Map; 35 36 private Map datamap, stkmap; 37 private File objfile; 38 private struct exec hdr; 39 40 public coredump_getkerinfo () 41 { 42 Symbol s; 43 44 s = lookup(identname("Sysmap", true)); 45 if (s == nil) { 46 panic("can't find 'Sysmap'"); 47 } 48 sbr = (struct pte *) (s->symvalue.offset); 49 s = lookup(identname("Syssize", true)); 50 if (s == nil) { 51 panic("can't find 'Syssize'"); 52 } 53 slr = (integer) (s->symvalue.offset); 54 printf("sbr %lx slr %lx\n", sbr, slr); 55 s = lookup(identname("masterpaddr", true)); 56 if (s == nil) { 57 panic("can't find 'masterpaddr'"); 58 } 59 fseek( 60 corefile, 61 datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin, 62 0 63 ); 64 get(corefile, masterpcbb); 65 masterpcbb = (masterpcbb&PG_PFNUM)*NBPG; 66 getpcb(); 67 } 68 69 /* 70 * Read the user area information from the core dump. 71 */ 72 73 public coredump_xreadin(mask, reg, signo) 74 int *mask; 75 Word reg[]; 76 short *signo; 77 { 78 register struct user *up; 79 register Word *savreg; 80 union { 81 struct user u; 82 char dummy[ctob(UPAGES)]; 83 } ustruct; 84 Symbol s; 85 86 objfile = fopen(objname, "r"); 87 if (objfile == nil) { 88 fatal("can't read \"%s\"", objname); 89 } 90 get(objfile, hdr); 91 if (vaddrs) { 92 datamap.begin = 0; 93 datamap.end = 0xffffffff; 94 stkmap.begin = 0xffffffff; 95 stkmap.end = 0xffffffff; 96 } else { 97 up = &(ustruct.u); 98 fread(up, ctob(UPAGES), 1, corefile); 99 # if vax || tahoe 100 savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]); 101 # else ifdef mc68000 102 savreg = (Word *) ( 103 &ustruct.dummy[ctob(UPAGES) - 10] - (NREG * sizeof(Word)) 104 ); 105 # endif 106 # ifdef IRIS 107 *mask = savreg[RPS]; 108 # else 109 *mask = savreg[PS]; 110 # endif 111 copyregs(savreg, reg); 112 *signo = up->u_arg[0]; 113 datamap.seekaddr = ctob(UPAGES); 114 stkmap.begin = USRSTACK - ctob(up->u_ssize); 115 stkmap.end = USRSTACK; 116 stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize); 117 switch (hdr.a_magic) { 118 case OMAGIC: 119 datamap.begin = CODESTART; 120 datamap.end = CODESTART + ctob(up->u_tsize) + ctob(up->u_dsize); 121 break; 122 123 case NMAGIC: 124 case ZMAGIC: 125 datamap.begin = (Address) 126 ptob(btop(ctob(up->u_tsize) - 1) + 1) + CODESTART; 127 datamap.end = datamap.begin + ctob(up->u_dsize); 128 break; 129 130 default: 131 fatal("bad magic number 0x%x", hdr.a_magic); 132 } 133 #ifdef UXMAG 134 /* 135 * Core dump not from this object file? 136 */ 137 if (hdr.a_magic != 0 and up->u_exdata.ux_mag != 0 and 138 hdr.a_magic != up->u_exdata.ux_mag) { 139 warning("core dump ignored"); 140 coredump = false; 141 fclose(corefile); 142 fclose(objfile); 143 start(nil, nil, nil); 144 } 145 #endif 146 } 147 } 148 149 public coredump_close() 150 { 151 fclose(objfile); 152 } 153 154 public coredump_readtext(buff, addr, nbytes) 155 char *buff; 156 Address addr; 157 int nbytes; 158 { 159 if (hdr.a_magic == OMAGIC or vaddrs) { 160 coredump_readdata(buff, addr, nbytes); 161 } else { 162 fseek(objfile, N_TXTOFF(hdr) + addr - CODESTART, 0); 163 fread(buff, nbytes, sizeof(Byte), objfile); 164 } 165 } 166 167 public coredump_readdata(buff, addr, nbytes) 168 char *buff; 169 Address addr; 170 int nbytes; 171 { 172 Address a; 173 174 a = addr; 175 if (a < datamap.begin) { 176 if (hdr.a_magic == OMAGIC) { 177 error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin); 178 } else { 179 coredump_readtext(buff, a, nbytes); 180 } 181 } else if (a > stkmap.end) { 182 error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end); 183 } else { 184 if (vaddrs) { 185 vreadfromfile(corefile, a, buff, nbytes); 186 } else { 187 readfromfile(corefile, a, buff, nbytes); 188 } 189 } 190 } 191 192 /* 193 * Read a block of data from a memory image, mapping virtual addresses. 194 * Have to watch out for page boundaries. 195 */ 196 197 private vreadfromfile (corefile, v, buff, nbytes) 198 File corefile; 199 Address v; 200 char *buff; 201 integer nbytes; 202 { 203 Address a; 204 integer i, remainder, pagesize; 205 char *bufp; 206 207 a = v; 208 pagesize = (integer) ptob(1); 209 remainder = pagesize - (a mod pagesize); 210 if (remainder >= nbytes) { 211 readfromfile(corefile, vmap(a), buff, nbytes); 212 } else { 213 readfromfile(corefile, vmap(a), buff, remainder); 214 a += remainder; 215 i = nbytes - remainder; 216 bufp = buff + remainder; 217 while (i > pagesize) { 218 readfromfile(corefile, vmap(a), bufp, pagesize); 219 a += pagesize; 220 bufp += pagesize; 221 i -= pagesize; 222 } 223 readfromfile(corefile, vmap(a), bufp, i); 224 } 225 } 226 227 private readfromfile (f, a, buff, nbytes) 228 File f; 229 Address a; 230 char *buff; 231 integer nbytes; 232 { 233 integer fileaddr; 234 235 if (a < stkmap.begin) { 236 fileaddr = datamap.seekaddr + a - datamap.begin; 237 } else { 238 fileaddr = stkmap.seekaddr + a - stkmap.begin; 239 } 240 fseek(f, fileaddr, 0); 241 fread(buff, nbytes, sizeof(Byte), f); 242 } 243