1 #ifndef lint 2 static char sccsid[] = "@(#)setup.c 1.1 (Berkeley) 02/25/86"; 3 #endif 4 5 /* 6 * adb - routines to read a.out+core at startup 7 */ 8 #include "defs.h" 9 #include <frame.h> 10 #include <ctype.h> 11 #include <sys/stat.h> 12 #include <sys/file.h> 13 #include <machine/rpb.h> 14 15 off_t datbas; /* offset of the base of the data segment */ 16 off_t stksiz; /* stack size in the core image */ 17 INT sigcode; /* belongs in head.h */ 18 19 char *symfil = "a.out"; 20 char *corfil = "core"; 21 22 setsym() 23 { 24 off_t loc; 25 struct exec hdr; 26 register struct nlist *sp; 27 int ssiz; 28 char *strtab, *malloc(); 29 30 fsym = getfile(symfil, 1); 31 txtmap.ufd = fsym; 32 if (read(fsym, (char *)&hdr, sizeof hdr) != sizeof hdr || 33 N_BADMAG(hdr)) { 34 txtmap.e1 = MAXFILE; 35 return; 36 } 37 filhdr = hdr; 38 loc = filhdr.a_text+filhdr.a_data; 39 txtmap.f1 = txtmap.f2 = N_TXTOFF(filhdr); 40 txtmap.b1 = 0; 41 switch (filhdr.a_magic) { 42 43 case OMAGIC: 44 txtmap.b1 = txtmap.e1 = 0; 45 txtmap.b2 = datbas = 0; 46 txtmap.e2 = loc; 47 break; 48 49 case ZMAGIC: 50 case NMAGIC: 51 txtmap.e1 = filhdr.a_text; 52 txtmap.b2 = datbas = round(filhdr.a_text, PAGSIZ); 53 txtmap.e2 = datbas + filhdr.a_data; 54 txtmap.f2 += txtmap.e1; 55 } 56 loc = N_SYMOFF(filhdr); 57 symtab = (struct nlist *) malloc(filhdr.a_syms); 58 esymtab = &symtab[filhdr.a_syms / sizeof (struct nlist)]; 59 if (symtab == NULL) 60 goto nospac; 61 lseek(fsym, loc, L_SET); 62 if (filhdr.a_syms == 0) 63 goto nosymt; 64 /* SHOULD SQUISH OUT STABS HERE!!! */ 65 if (read(fsym, symtab, filhdr.a_syms) != filhdr.a_syms) 66 goto readerr; 67 if (read(fsym, &ssiz, sizeof (ssiz)) != sizeof (ssiz)) 68 goto oldfmt; 69 strtab = malloc(ssiz); 70 if (strtab == 0) 71 goto nospac; 72 *(int *)strtab = ssiz; 73 ssiz -= sizeof (ssiz); 74 if (read(fsym, strtab + sizeof (ssiz), ssiz) != ssiz) 75 goto readerr; 76 for (sp = symtab; sp < esymtab; sp++) 77 if (sp->n_un.n_strx) 78 /* SHOULD PERFORM RANGE CHECK HERE */ 79 sp->n_un.n_name = strtab + sp->n_un.n_strx; 80 nosymt: 81 if (INKERNEL(filhdr.a_entry)) { 82 txtmap.b1 += KERNOFF; 83 txtmap.e1 += KERNOFF; 84 txtmap.b2 += KERNOFF; 85 txtmap.e2 += KERNOFF; 86 } 87 return; 88 readerr: 89 printf("Error reading symbol|string table\n"); 90 exit(1); 91 nospac: 92 printf("Not enough space for symbol|string table\n"); 93 exit(1); 94 oldfmt: 95 printf("Old format a.out - no string table\n"); 96 exit(1); 97 } 98 99 setcor() 100 { 101 102 fcor = datmap.ufd = getfile(corfil,2); 103 if (kernel && fcor != -1 && INKERNEL(filhdr.a_entry)) { 104 struct stat stb; 105 106 kcore = 1; 107 fstat(fcor, &stb); 108 datmap.b1 = 0; 109 datmap.e1 = -1; 110 if (kernel == 0 && (stb.st_mode & S_IFREG)) 111 datmap.b1 = 0xc0000000; 112 lookup("_Sysmap"); 113 sbr = (struct pte *)cursym->n_value; 114 lookup("_Syssize"); 115 slr = cursym->n_value; 116 printf("sbr %X slr %X\n", sbr, slr); 117 lookup("_masterpaddr"); 118 physrw(fcor, cursym->n_value&~0xc0000000, &masterpcbb, 1); 119 masterpcbb = (masterpcbb&PG_PFNUM)*NBPG; 120 getpcb(); 121 findstackframe(); 122 return; 123 } 124 if (read(fcor, (char *)&u, ctob(UPAGES))!=ctob(UPAGES) || 125 !INUDOT(u.u_pcb.pcb_ksp) || !INSTACK(u.u_pcb.pcb_usp)) { 126 datmap.e1 = MAXFILE; 127 return; 128 } 129 signo = u.u_arg[0]; 130 sigcode = u.u_code; 131 filhdr.a_text = ctob(u.u_tsize); 132 filhdr.a_data = ctob(u.u_dsize); 133 stksiz = ctob(u.u_ssize); 134 switch (filhdr.a_magic) { 135 136 case OMAGIC: 137 datmap.b1 = 0; 138 datmap.e1 = filhdr.a_text+filhdr.a_data; 139 datmap.f2 = ctob(UPAGES) + datmap.e1; 140 break; 141 142 case NMAGIC: 143 case ZMAGIC: 144 datmap.b1 = round(filhdr.a_text, PAGSIZ); 145 datmap.e1 = datmap.b1 + filhdr.a_data; 146 datmap.f2 = ctob(UPAGES) + filhdr.a_data; 147 break; 148 } 149 datbas = datmap.b1; 150 datmap.f1 = ctob(UPAGES); 151 datmap.b2 = MAXSTOR - stksiz; 152 datmap.e2 = MAXSTOR; 153 } 154 155 getpcb() 156 { 157 158 lseek(fcor, KVTOPH(masterpcbb), L_SET); 159 read(fcor, &pcb, sizeof (struct pcb)); 160 printf("p0br %X p0lr %X p2br %X p2lr %X\n", 161 pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p2br, pcb.pcb_p2lr); 162 } 163 164 caddr_t rpb, erpb; 165 caddr_t intstack, eintstack; 166 caddr_t ustack, eustack; 167 struct frame *getframe(); 168 struct frame *checkintstack(); 169 170 /* 171 * Find the current stack frame when debugging the kernel. 172 * If we're looking at a crash dump and this was not a ``clean'' 173 * crash, then we must search the interrupt stack carefully 174 * looking for a valid frame. 175 */ 176 findstackframe() 177 { 178 char *panicstr, buf[256]; 179 register struct frame *fp; 180 caddr_t addr; 181 register char *cp; 182 int mask; 183 184 if (lookup("_panicstr") == 0) 185 return; 186 lseek(fcor, cursym->n_value&~0xc0000000, L_SET); 187 read(fcor, &panicstr, sizeof (panicstr)); 188 if (panicstr == 0) 189 return; 190 lseek(fcor, ((off_t)panicstr)&~0xc0000000, L_SET); 191 read(fcor, buf, sizeof (buf)); 192 for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++) 193 if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp))) 194 *cp = '?'; 195 if (*cp) 196 *cp = '\0'; 197 printf("panic: %s\n", buf); 198 /* 199 * After a panic, look at the top of the rpb stack to 200 * find a stack frame. If this was a clean crash, 201 * i.e. one which left the interrupt and kernel stacks 202 * in a reasonable state, then we should find a pointer 203 * to the proper stack frame here (at location intstack-4). 204 * If we don't find a reasonable frame here, then we 205 * must search down through the interrupt stack. 206 */ 207 intstack = (caddr_t)lookup("_intstack")->n_value; 208 #define NISP 3 /* from locore.s */ 209 eintstack = intstack + NISP*NBPG; 210 rpb = (caddr_t)lookup("_rsstk")->n_value; /* XXX */ 211 erpb = rpb + NBPG - 2*sizeof (long); 212 lookup("_u"); 213 ustack = 214 (caddr_t)(cursym->n_value + (int)&((struct user *)0)->u_stack[0]); 215 eustack = (caddr_t)(cursym->n_value + ctob(UPAGES)); 216 physrw(fcor, KVTOPH((int)intstack-2*sizeof (caddr_t)), &addr, 1); 217 fp = getframe(fcor, addr); 218 if (fp == 0) 219 fp = checkintstack(); 220 /* search kernel stack? */ 221 if (fp == 0) { 222 printf("can't locate stack frame\n"); 223 return; 224 } 225 /* probably shouldn't clobber pcb, but for now this is easy */ 226 pcb.pcb_fp = (int)addr; 227 pcb.pcb_pc = fp->fr_savpc; 228 } 229 230 /* 231 * Search interrupt stack for a valid frame. 232 */ 233 struct frame * 234 checkintstack(fcor) 235 { 236 char stack[NISP*NBPG]; 237 off_t off = vtophys(intstack); 238 struct frame *fp; 239 register caddr_t addr; 240 241 if (off == -1 || lseek(fcor, off, L_SET) != off || 242 read(fcor, stack, sizeof (stack)) != sizeof (stack)) 243 return ((struct frame *)0); 244 addr = eintstack; 245 do { 246 addr -= sizeof (caddr_t); 247 fp = (struct frame *)&stack[addr - intstack]; 248 } while (addr >= intstack + sizeof (struct frame) - sizeof (caddr_t) && 249 !checkframe(fp)); 250 return (addr < intstack+sizeof (struct frame) ? (struct frame *)0 : fp); 251 } 252 253 /* 254 * Get a stack frame and verify it looks like 255 * something which might be on a kernel stack. 256 */ 257 struct frame * 258 getframe(fcor, fp) 259 int fcor; 260 caddr_t fp; 261 { 262 static struct frame frame; 263 off_t off; 264 265 if (!kstackaddr(fp) || (off = vtophys(fp)) == -1) 266 return ((struct frame *)0); 267 off -= sizeof (struct frame) - sizeof (caddr_t); 268 if (lseek(fcor, off, L_SET) != off || 269 read(fcor, &frame, sizeof (frame)) != sizeof (frame)) 270 return ((struct frame *)0); 271 if (!checkframe(&frame)) 272 return ((struct frame *)0); 273 return (&frame); 274 } 275 276 /* 277 * Check a call frame to see if it's ok as 278 * a kernel stack frame. 279 */ 280 checkframe(fp) 281 register struct frame *fp; 282 { 283 284 if (!kstackaddr(fp->fr_savfp)) 285 return (0); 286 return (within(fp->fr_savpc, txtmap.b1, txtmap.e1)); 287 } 288 289 /* 290 * Check if an address is in one of the kernel's stacks: 291 * interrupt stack, rpb stack (during restart sequence), 292 * or u. stack. 293 */ 294 kstackaddr(addr) 295 caddr_t addr; 296 { 297 298 return (within(addr, intstack, eintstack) || 299 within(addr, rpb + sizeof (struct rpb), erpb) || 300 within(addr, ustack, eustack)); 301 } 302 303 create(f) 304 char *f; 305 { 306 register int fd; 307 308 fd = creat(f, 0644); 309 if (fd < 0) 310 return (-1); 311 close(fd); 312 return (open(f, wtflag)); 313 } 314 315 getfile(filnam, cnt) 316 char *filnam; 317 { 318 register int fsym; 319 320 if (eqstr(filnam, "-")) 321 return (-1); 322 fsym = open(filnam, wtflag); 323 if (fsym < 0 && xargc > cnt) { 324 if (wtflag) 325 fsym = create(filnam); 326 if (fsym < 0) 327 printf("cannot open `%s'\n", filnam); 328 } 329 return (fsym); 330 } 331 332 setvar() 333 { 334 335 var[varchk('b')] = datbas; 336 var[varchk('d')] = filhdr.a_data; 337 var[varchk('e')] = filhdr.a_entry; 338 var[varchk('m')] = filhdr.a_magic; 339 var[varchk('s')] = stksiz; 340 var[varchk('t')] = filhdr.a_text; 341 } 342