clean up awk syntax
[unix-history] / usr / src / old / adb / adb.tahoe / setup.c
CommitLineData
40886ada
SL
1#ifndef lint
2static char sccsid[] = "@(#)setup.c 1.1 (Berkeley) %G%";
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
15off_t datbas; /* offset of the base of the data segment */
16off_t stksiz; /* stack size in the core image */
17INT sigcode; /* belongs in head.h */
18
19char *symfil = "a.out";
20char *corfil = "core";
21
22setsym()
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;
80nosymt:
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;
88readerr:
89 printf("Error reading symbol|string table\n");
90 exit(1);
91nospac:
92 printf("Not enough space for symbol|string table\n");
93 exit(1);
94oldfmt:
95 printf("Old format a.out - no string table\n");
96 exit(1);
97}
98
99setcor()
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
155getpcb()
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
164caddr_t rpb, erpb;
165caddr_t intstack, eintstack;
166caddr_t ustack, eustack;
167struct frame *getframe();
168struct 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 */
176findstackframe()
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 */
233struct frame *
234checkintstack(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 */
257struct frame *
258getframe(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 */
280checkframe(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 */
294kstackaddr(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
303create(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
315getfile(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
332setvar()
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}