new version from Chris Torek
[unix-history] / usr / src / old / adb / adb.vax / setup.c
CommitLineData
eb1efbca 1static char sccsid[] = "@(#)setup.c 4.11 (Berkeley) 87/12/21";
af975fa6
BJ
2/*
3 * adb - routines to read a.out+core at startup
4 */
5#include "defs.h"
ab398a39
SL
6#include <frame.h>
7#include <ctype.h>
6094e621 8#include <sys/stat.h>
ab398a39
SL
9#include <sys/file.h>
10#include <vax/rpb.h>
af975fa6
BJ
11
12off_t datbas; /* offset of the base of the data segment */
13off_t stksiz; /* stack size in the core image */
14INT sigcode; /* belongs in head.h */
15
16char *symfil = "a.out";
17char *corfil = "core";
18
19setsym()
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;
ab398a39 58 lseek(fsym, loc, L_SET);
af975fa6
BJ
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++)
eb1efbca 74 if (sp->n_un.n_strx)
af975fa6
BJ
75 /* SHOULD PERFORM RANGE CHECK HERE */
76 sp->n_un.n_name = strtab + sp->n_un.n_strx;
77nosymt:
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;
85readerr:
86 printf("Error reading symbol|string table\n");
87 exit(1);
88nospac:
89 printf("Not enough space for symbol|string table\n");
90 exit(1);
91oldfmt:
92 printf("Old format a.out - no string table\n");
93 exit(1);
94}
95
96setcor()
97{
98
99 fcor = datmap.ufd = getfile(corfil,2);
52bff713 100 if (kernel && fcor != -1 && INKERNEL(filhdr.a_entry)) {
af975fa6
BJ
101 struct stat stb;
102
128eca8b 103 kcore = 1;
af975fa6
BJ
104 fstat(fcor, &stb);
105 datmap.b1 = 0;
106 datmap.e1 = -1;
6d4468aa
BJ
107 if (kernel == 0 && (stb.st_mode & S_IFREG))
108 datmap.b1 = 0x80000000;
6eadceb1
BJ
109 lookup("_Sysmap");
110 sbr = cursym->n_value;
111 lookup("_Syssize");
112 slr = cursym->n_value;
7de0b1f0 113 printf("sbr %x slr %x\n", sbr, slr);
52bff713 114 lookup("_masterpaddr");
f81bba3d
SL
115 physrw(fcor, KVTOPH(cursym->n_value), &masterpcbb, 1);
116 masterpcbb = (masterpcbb&PG_PFNUM)*NBPG;
6eadceb1 117 getpcb();
ab398a39 118 findstackframe();
af975fa6
BJ
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;
af975fa6
BJ
150}
151
6eadceb1
BJ
152getpcb()
153{
128eca8b 154
f81bba3d 155 lseek(fcor, KVTOPH(masterpcbb), L_SET);
6eadceb1 156 read(fcor, &pcb, sizeof (struct pcb));
128eca8b 157 pcb.pcb_p0lr &= ~AST_CLR;
7de0b1f0 158 printf("p0br %x p0lr %x p1br %x p1lr %x\n",
6eadceb1 159 pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);
6eadceb1
BJ
160}
161
ab398a39
SL
162caddr_t rpb, scb;
163caddr_t intstack, eintstack;
164caddr_t ustack, eustack;
165struct frame *getframe();
166struct 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 */
174findstackframe()
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;
f81bba3d 184 lseek(fcor, KVTOPH(cursym->n_value), L_SET);
ab398a39
SL
185 read(fcor, &panicstr, sizeof (panicstr));
186 if (panicstr == 0)
187 return;
f81bba3d 188 lseek(fcor, KVTOPH((off_t)panicstr), L_SET);
ab398a39
SL
189 read(fcor, buf, sizeof (buf));
190 for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++)
f81bba3d 191 if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))
ab398a39
SL
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);
f81bba3d 213 physrw(fcor, KVTOPH((int)scb - sizeof (caddr_t)), &addr, 1);
ab398a39
SL
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 */
234struct frame *
235checkintstack(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 */
258struct frame *
259getframe(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 */
280checkframe(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 */
296kstackaddr(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
af975fa6
BJ
305create(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
317getfile(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
334setvar()
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}