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