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