1 /* Copyright (c) 1982 Regents of the University of California */ 2 3 static char sccsid[] = "@(#)coredump.c 1.5 (Berkeley) 06/23/84"; 4 5 /* 6 * Deal with the core dump anachronism. 7 */ 8 9 #include "defs.h" 10 #include "coredump.h" 11 #include "machine.h" 12 #include "object.h" 13 #include "main.h" 14 #include <sys/param.h> 15 #include <sys/dir.h> 16 #include <machine/psl.h> 17 #include <machine/pte.h> 18 #include <sys/user.h> 19 #include <sys/vm.h> 20 #include <machine/reg.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 #define MAXSTKADDR (0x80000000 - ctob(UPAGES)) /* highest stack address */ 30 31 typedef struct { 32 Address begin; 33 Address end; 34 Address seekaddr; 35 } Map; 36 37 private Map datamap, stkmap; 38 private File objfile; 39 private struct exec hdr; 40 41 /* 42 * Read the user area information from the core dump. 43 */ 44 45 public coredump_xreadin(mask, reg, signo) 46 int *mask; 47 Word reg[]; 48 int *signo; 49 { 50 register struct user *up; 51 register Word *savreg; 52 union { 53 struct user u; 54 char dummy[ctob(UPAGES)]; 55 } ustruct; 56 57 objfile = fopen(objname, "r"); 58 if (objfile == nil) { 59 fatal("can't read \"%s\"", objname); 60 } 61 get(objfile, hdr); 62 up = &(ustruct.u); 63 fread(up, ctob(UPAGES), 1, corefile); 64 savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]); 65 *mask = savreg[PS]; 66 reg[0] = savreg[R0]; 67 reg[1] = savreg[R1]; 68 reg[2] = savreg[R2]; 69 reg[3] = savreg[R3]; 70 reg[4] = savreg[R4]; 71 reg[5] = savreg[R5]; 72 reg[6] = savreg[R6]; 73 reg[7] = savreg[R7]; 74 reg[8] = savreg[R8]; 75 reg[9] = savreg[R9]; 76 reg[10] = savreg[R10]; 77 reg[11] = savreg[R11]; 78 reg[ARGP] = savreg[AP]; 79 reg[FRP] = savreg[FP]; 80 reg[STKP] = savreg[SP]; 81 reg[PROGCTR] = savreg[PC]; 82 *signo = up->u_arg[0]; 83 datamap.seekaddr = ctob(UPAGES); 84 stkmap.begin = MAXSTKADDR - ctob(up->u_ssize); 85 stkmap.end = MAXSTKADDR; 86 stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize); 87 switch (hdr.a_magic) { 88 case OMAGIC: 89 datamap.begin = 0; 90 datamap.end = ctob(up->u_tsize) + ctob(up->u_dsize); 91 break; 92 93 case NMAGIC: 94 case ZMAGIC: 95 datamap.begin = (Address) ptob(btop(ctob(up->u_tsize) - 1) + 1); 96 datamap.end = datamap.begin + ctob(up->u_dsize); 97 break; 98 99 default: 100 fatal("bad magic number 0x%x", hdr.a_magic); 101 } 102 /* 103 * Core dump not from this object file? 104 */ 105 if (hdr.a_magic != 0 and up->u_exdata.ux_mag != 0 and 106 hdr.a_magic != up->u_exdata.ux_mag) { 107 warning("core dump ignored"); 108 coredump = false; 109 fclose(corefile); 110 fclose(objfile); 111 start(nil, nil, nil); 112 } 113 } 114 115 public coredump_close() 116 { 117 fclose(objfile); 118 } 119 120 public coredump_readtext(buff, addr, nbytes) 121 char *buff; 122 Address addr; 123 int nbytes; 124 { 125 if (hdr.a_magic == OMAGIC) { 126 coredump_readdata(buff, addr, nbytes); 127 } else { 128 fseek(objfile, N_TXTOFF(hdr) + addr, 0); 129 fread(buff, nbytes, sizeof(Byte), objfile); 130 } 131 } 132 133 public coredump_readdata(buff, addr, nbytes) 134 char *buff; 135 Address addr; 136 int nbytes; 137 { 138 if (addr < datamap.begin) { 139 if (hdr.a_magic == OMAGIC) { 140 error("data address 0x%x too low (lb = 0x%x)", addr, datamap.begin); 141 } else { 142 coredump_readtext(buff, addr, nbytes); 143 } 144 } else if (addr > stkmap.end) { 145 error("data address 0x%x too high (ub = 0x%x)", addr, stkmap.end); 146 } else if (addr < stkmap.begin) { 147 fseek(corefile, datamap.seekaddr + addr - datamap.begin, 0); 148 fread(buff, nbytes, sizeof(Byte), corefile); 149 } else { 150 fseek(corefile, stkmap.seekaddr + addr - stkmap.begin, 0); 151 fread(buff, nbytes, sizeof(Byte), corefile); 152 } 153 } 154