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