Commit | Line | Data |
---|---|---|
2bfe20cf ML |
1 | /* |
2 | * Symbolic debugging info interface. | |
3 | * | |
4 | * Here we generate pseudo-ops that cause the assembler to put | |
5 | * symbolic debugging information into the object file. | |
6 | */ | |
7 | ||
e804469b | 8 | static char *sccsid ="@(#)stab.c 1.4 (Berkeley) 2/2/83"; |
2bfe20cf ML |
9 | |
10 | #include "mfile1" | |
11 | ||
12 | #include <sys/types.h> | |
13 | #include <a.out.h> | |
14 | #include <stab.h> | |
15 | ||
16 | #define private static | |
17 | #define and && | |
18 | #define or || | |
19 | #define not ! | |
20 | #define div / | |
21 | #define mod % | |
22 | #define nil 0 | |
23 | ||
24 | #define bytes(bits) ((bits) / SZCHAR) | |
25 | #define bsize(p) bytes(dimtab[p->sizoff]) /* size in bytes of a symbol */ | |
26 | ||
27 | #define NILINDEX -1 | |
28 | #define FORWARD -2 | |
29 | ||
dd5592c6 ML |
30 | typedef int Boolean; |
31 | ||
32 | #define false 0 | |
33 | #define true 1 | |
2bfe20cf ML |
34 | |
35 | extern int ddebug; | |
36 | extern int gdebug; | |
37 | extern char *malloc(); | |
38 | ||
39 | int stabLCSYM; | |
40 | ||
30636230 ML |
41 | /* |
42 | * Flag for producing either sdb or dbx symbol information. | |
43 | */ | |
279a32fc | 44 | int oldway = false; |
30636230 | 45 | |
2bfe20cf ML |
46 | /* |
47 | * Generate debugging info for a parameter. | |
48 | * The offset isn't known when it is first entered into the symbol table | |
49 | * since the types are read later. | |
50 | */ | |
51 | ||
52 | fixarg(p) | |
53 | struct symtab *p; | |
54 | { | |
30636230 ML |
55 | if (oldway) { |
56 | old_fixarg(p); | |
57 | } else if (gdebug) { | |
2bfe20cf ML |
58 | printf("\t.stabs\t\"%s:p", p->sname); |
59 | gentype(p); | |
60 | printf("\",0x%x,0,%d,%d\n", N_PSYM, bsize(p), bytes(argoff)); | |
61 | } | |
62 | } | |
63 | ||
64 | /* | |
65 | * Generate debugging info for a given symbol. | |
66 | */ | |
67 | ||
68 | outstab(sym) | |
69 | struct symtab *sym; | |
70 | { | |
71 | register struct symtab *p; | |
72 | char *classname; | |
73 | int offset; | |
74 | Boolean ignore; | |
75 | static Boolean firsttime = true; | |
76 | ||
30636230 ML |
77 | if (oldway) { |
78 | old_outstab(sym); | |
79 | } else if (gdebug) { | |
2bfe20cf ML |
80 | if (firsttime) { |
81 | firsttime = false; | |
82 | inittypes(); | |
83 | } | |
84 | ignore = false; | |
85 | p = sym; | |
86 | offset = bytes(p->offset); | |
87 | switch (p->sclass) { | |
88 | case REGISTER: | |
89 | classname = "r"; | |
90 | offset = p->offset; | |
91 | break; | |
92 | ||
93 | /* | |
94 | * Locals are the default class. | |
95 | */ | |
96 | case AUTO: | |
97 | classname = ""; | |
98 | break; | |
99 | ||
100 | case STATIC: | |
101 | if (ISFTN(p->stype)) { | |
102 | ignore = true; | |
103 | } else if (p->slevel <= 1) { | |
104 | classname = "S"; | |
105 | } else { | |
106 | classname = "V"; | |
107 | } | |
108 | break; | |
109 | ||
110 | case EXTDEF: | |
111 | case EXTERN: | |
112 | if (ISFTN(p->stype)) { | |
113 | ignore = true; | |
114 | } else { | |
115 | classname = "G"; | |
116 | } | |
117 | break; | |
118 | ||
119 | case TYPEDEF: | |
120 | classname = "t"; | |
121 | break; | |
122 | ||
123 | case PARAM: | |
124 | case MOS: | |
125 | case MOU: | |
126 | case MOE: | |
127 | ignore = true; | |
128 | break; | |
129 | ||
130 | case ENAME: | |
131 | case UNAME: | |
132 | case STNAME: | |
133 | entertype(p->stype, NILINDEX, FORWARD, dimtab[p->sizoff + 3]); | |
134 | ignore = true; | |
135 | break; | |
136 | ||
137 | default: | |
138 | if ((p->sclass&FIELD) == 0) { | |
139 | printf("/* no info for %s (%d) */\n", p->sname, p->sclass); | |
140 | } | |
141 | ignore = true; | |
142 | break; | |
143 | } | |
144 | if (not ignore) { | |
145 | printf("\t.stabs\t\"%s:%s", p->sname, classname); | |
146 | gentype(p); | |
147 | geninfo(p); | |
148 | } | |
149 | } | |
150 | } | |
151 | ||
152 | /* | |
153 | * Since type names are lost in the travels and because C has | |
154 | * structural type equivalence we keep a table of type words that | |
155 | * we've already seen. The first time we see a type, it is assigned | |
156 | * (inline) a number and future references just list that number. | |
157 | * Structures, unions, enums, and arrays must be handled carefully | |
158 | * since not all the necessary information is in the type word. | |
159 | */ | |
160 | ||
161 | typedef struct Typeid *Typeid; | |
162 | ||
163 | struct Typeid { | |
164 | TWORD tword; | |
165 | int tarray; | |
166 | int tstruct; | |
167 | int tstrtag; | |
168 | int tnum; | |
169 | Typeid chain; | |
170 | }; | |
171 | ||
172 | #define TABLESIZE 2003 | |
173 | ||
174 | private int tcount = 1; | |
175 | private int t_int, t_char; | |
176 | private Typeid typetable[TABLESIZE]; | |
177 | ||
178 | /* | |
179 | * Look for the given type word in the type table. | |
180 | */ | |
181 | ||
182 | private Typeid typelookup(type, arrindex, strindex, strtag) | |
183 | TWORD type; | |
184 | int arrindex; | |
185 | int strindex; | |
186 | int strtag; | |
187 | { | |
188 | register TWORD tword; | |
189 | register int i1, i2; | |
190 | Typeid t; | |
191 | ||
192 | t = typetable[type mod TABLESIZE]; | |
193 | while (t != nil) { | |
194 | if (t->tword == type and | |
195 | strindex == t->tstruct and strtag == t->tstrtag) { | |
196 | if (arrindex == NILINDEX) { | |
197 | break; | |
198 | } else { | |
199 | tword = type >> TSHIFT; | |
200 | i1 = arrindex; | |
201 | i2 = t->tarray; | |
202 | while (ISARY(tword) and dimtab[i1] == dimtab[i2]) { | |
203 | ++i1; | |
204 | ++i2; | |
205 | tword >>= TSHIFT; | |
206 | } | |
207 | if (!ISARY(tword)) { | |
208 | break; | |
209 | } | |
210 | } | |
211 | } | |
212 | t = t->chain; | |
213 | } | |
214 | return t; | |
215 | } | |
216 | ||
217 | /* | |
218 | * Enter a type word and associated symtab indices into the type table. | |
219 | */ | |
220 | ||
221 | private int entertype(type, arrindex, strindex, strtag) | |
222 | TWORD type; | |
223 | int arrindex; | |
224 | int strindex; | |
225 | int strtag; | |
226 | { | |
227 | register Typeid t; | |
228 | register int i; | |
229 | ||
230 | t = (Typeid) malloc(sizeof(struct Typeid)); | |
231 | t->tword = type; | |
232 | t->tarray = arrindex; | |
233 | t->tstruct = strindex; | |
234 | t->tstrtag = strtag; | |
235 | t->tnum = tcount; | |
236 | ++tcount; | |
237 | i = type mod TABLESIZE; | |
238 | t->chain = typetable[i]; | |
239 | typetable[i] = t; | |
240 | return t->tnum; | |
241 | } | |
242 | ||
243 | /* | |
244 | * Change the information associated with a type table entry. | |
245 | * Since I'm lazy this just creates a new entry with the number | |
246 | * as the old one. | |
247 | */ | |
248 | ||
249 | private reentertype(typeid, type, arrindex, strindex, strtag) | |
250 | Typeid typeid; | |
251 | TWORD type; | |
252 | int arrindex; | |
253 | int strindex; | |
254 | int strtag; | |
255 | { | |
256 | register Typeid t; | |
257 | register int i; | |
258 | ||
259 | t = (Typeid) malloc(sizeof(struct Typeid)); | |
260 | t->tword = type; | |
261 | t->tarray = arrindex; | |
262 | t->tstruct = strindex; | |
263 | t->tstrtag = strtag; | |
264 | t->tnum = typeid->tnum; | |
265 | i = type mod TABLESIZE; | |
266 | t->chain = typetable[i]; | |
267 | typetable[i] = t; | |
268 | } | |
269 | ||
270 | /* | |
271 | * Initialize type table with predefined types. | |
272 | */ | |
273 | ||
274 | #define builtintype(type) entertype(type, NILINDEX, NILINDEX, NILINDEX) | |
275 | ||
276 | private inittypes() | |
277 | { | |
278 | int t; | |
279 | ||
280 | t_int = builtintype(INT); | |
281 | t_char = builtintype(CHAR); | |
282 | maketype("int", t_int, t_int, 0x80000000L, 0x7fffffffL); | |
283 | maketype("char", t_char, t_char, 0L, 127L); | |
284 | maketype("long", builtintype(LONG), t_int, 0x80000000L, 0x7fffffffL); | |
285 | maketype("short", builtintype(SHORT), t_int, 0xffff8000L, 0x7fffL); | |
286 | maketype("unsigned char", builtintype(UCHAR), t_int, 0L, 255L); | |
287 | maketype("unsigned short", builtintype(USHORT), t_int, 0L, 0xffffL); | |
288 | maketype("unsigned long", builtintype(ULONG), t_int, 0L, 0xffffffffL); | |
289 | maketype("unsigned int", builtintype(UNSIGNED), t_int, 0L, 0xffffffffL); | |
290 | maketype("float", builtintype(FLOAT), t_int, 4L, 0L); | |
291 | maketype("double", builtintype(DOUBLE), t_int, 8L, 0L); | |
292 | t = builtintype(UNDEF); | |
293 | printf("\t.stabs\t\"void:t%d=%d", t, t); | |
294 | geninfo(nil); | |
dd5592c6 ML |
295 | t = builtintype(FARG); |
296 | printf("\t.stabs\t\"???:t%d=%d", t, t_int); | |
297 | geninfo(nil); | |
2bfe20cf ML |
298 | } |
299 | ||
300 | /* | |
301 | * Generate info for a new range type. | |
302 | */ | |
303 | ||
304 | private maketype(name, tnum, eqtnum, lower, upper) | |
305 | char *name; | |
306 | int tnum, eqtnum; | |
307 | long lower, upper; | |
308 | { | |
309 | printf("\t.stabs\t\"%s:t%d=r%d;%d;%d;", name, tnum, eqtnum, lower, upper); | |
310 | geninfo(nil); | |
311 | } | |
312 | ||
313 | /* | |
314 | * Generate debugging information for the given type of the given symbol. | |
315 | */ | |
316 | ||
317 | private gentype(sym) | |
318 | struct symtab *sym; | |
319 | { | |
320 | register struct symtab *p; | |
321 | register TWORD t; | |
322 | register TWORD basictype; | |
323 | register Typeid typeid; | |
324 | int i, arrindex, strindex, strtag; | |
325 | ||
326 | p = sym; | |
327 | t = p->stype; | |
328 | if (ISFTN(t)) { | |
329 | t = DECREF(t); | |
330 | } | |
331 | basictype = BTYPE(t); | |
332 | if (ISARY(t)) { | |
333 | arrindex = p->dimoff; | |
334 | } else { | |
335 | arrindex = NILINDEX; | |
336 | } | |
337 | if (basictype == STRTY or basictype == UNIONTY or basictype == ENUMTY) { | |
338 | strindex = dimtab[p->sizoff + 1]; | |
339 | if (strindex == -1) { | |
340 | strindex = FORWARD; | |
341 | strtag = dimtab[p->sizoff + 3]; | |
342 | } else { | |
343 | strtag = NILINDEX; | |
344 | } | |
345 | } else { | |
346 | strindex = NILINDEX; | |
347 | strtag = NILINDEX; | |
348 | } | |
349 | i = arrindex; | |
350 | typeid = typelookup(t, arrindex, strindex, strtag); | |
351 | while (t != basictype and typeid == nil) { | |
352 | printf("%d=", entertype(t, i, strindex, strtag)); | |
353 | switch (t&TMASK) { | |
354 | case PTR: | |
355 | printf("*"); | |
356 | break; | |
357 | ||
358 | case FTN: | |
359 | printf("f"); | |
360 | break; | |
361 | ||
362 | case ARY: | |
363 | printf("ar%d;0;%d;", t_int, dimtab[i++] - 1); | |
364 | break; | |
365 | } | |
366 | t = DECREF(t); | |
367 | if (t == basictype) { | |
368 | typeid = typelookup(t, NILINDEX, strindex, strtag); | |
369 | } else { | |
370 | typeid = typelookup(t, i, strindex, strtag); | |
371 | } | |
372 | } | |
373 | if (typeid == nil) { | |
374 | if (strindex == FORWARD) { | |
375 | typeid = typelookup(t, NILINDEX, FORWARD, dimtab[p->sizoff + 3]); | |
376 | if (typeid == nil) { | |
377 | cerror("unbelievable forward reference"); | |
378 | } | |
379 | printf("%d", typeid->tnum); | |
380 | } else { | |
381 | genstruct(t, NILINDEX, strindex, p->sname, bsize(p)); | |
382 | } | |
383 | } else { | |
384 | printf("%d", typeid->tnum); | |
385 | } | |
386 | } | |
387 | ||
388 | /* | |
389 | * Generate type information for structures, unions, and enumerations. | |
390 | */ | |
391 | ||
392 | private genstruct(t, structid, index, name, size) | |
393 | TWORD t; | |
394 | int structid; | |
395 | int index; | |
396 | char *name; | |
397 | int size; | |
398 | { | |
399 | register int i; | |
400 | register struct symtab *field; | |
401 | int id; | |
402 | ||
403 | if (structid == NILINDEX) { | |
404 | id = entertype(t, NILINDEX, index, NILINDEX); | |
405 | } else { | |
406 | id = structid; | |
407 | } | |
408 | switch (t) { | |
409 | case STRTY: | |
410 | case UNIONTY: | |
411 | printf("%d=%c%d", id, t == STRTY ? 's' : 'u', size); | |
412 | i = index; | |
413 | while (dimtab[i] != -1) { | |
414 | field = &stab[dimtab[i]]; | |
415 | printf("%s:", field->sname); | |
416 | gentype(field); | |
417 | if (field->sclass > FIELD) { | |
418 | printf(",%d,%d;", field->offset, field->sclass - FIELD); | |
419 | } else { | |
420 | printf(",%d,%d;", field->offset, | |
421 | tsize(field->stype, field->dimoff, field->sizoff)); | |
422 | } | |
423 | ++i; | |
424 | } | |
425 | putchar(';'); | |
426 | break; | |
427 | ||
428 | case ENUMTY: | |
429 | printf("%d=e", id); | |
430 | i = index; | |
431 | while (dimtab[i] != -1) { | |
432 | field = &stab[dimtab[i]]; | |
433 | printf("%s:%d,", field->sname, field->offset); | |
434 | i++; | |
435 | } | |
436 | break; | |
437 | ||
438 | default: | |
439 | cerror("couldn't find basic type %d for %s\n", t, name); | |
440 | break; | |
441 | } | |
442 | } | |
443 | ||
444 | /* | |
445 | * Generate offset and size info. | |
446 | */ | |
447 | ||
448 | private geninfo(p) | |
449 | register struct symtab *p; | |
450 | { | |
451 | if (p == nil) { | |
452 | printf("\",0x%x,0,0,0\n", N_LSYM); | |
453 | } else { | |
454 | switch (p->sclass) { | |
455 | case EXTERN: | |
456 | case EXTDEF: | |
457 | if (ISFTN(p->stype)) { | |
458 | printf("\",0x%x,0,%d,_%s\n", N_FUN, bsize(p), p->sname); | |
459 | } else { | |
dd5592c6 | 460 | printf("\",0x%x,0,%d,0\n", N_GSYM, bsize(p)); |
2bfe20cf ML |
461 | } |
462 | break; | |
463 | ||
464 | case STATIC: | |
465 | if (ISFTN(p->stype)) { | |
466 | printf("\",0x%x,0,%d,_%s\n", N_FUN, bsize(p), p->sname); | |
467 | } else if (p->slevel > 1) { | |
468 | printf("\",0x%x,0,%d,L%d\n", N_STSYM, bsize(p), p->offset); | |
469 | } else { | |
470 | printf("\",0x%x,0,%d,_%s\n", N_LCSYM, bsize(p), p->sname); | |
471 | } | |
472 | break; | |
473 | ||
474 | case REGISTER: | |
475 | printf("\",0x%x,0,%d,%d\n", N_RSYM, bsize(p), p->offset); | |
476 | break; | |
477 | ||
478 | case PARAM: | |
479 | printf("\",0x%x,0,%d,%d\n", N_PSYM, bsize(p), bytes(argoff)); | |
480 | break; | |
481 | ||
482 | default: | |
483 | printf("\",0x%x,0,%d,%d\n", N_LSYM, bsize(p), bytes(p->offset)); | |
484 | break; | |
485 | } | |
486 | } | |
487 | } | |
488 | ||
489 | /* | |
490 | * Generate information for a newly-defined structure. | |
491 | */ | |
492 | ||
493 | outstruct(szindex, paramindex) | |
494 | int szindex, paramindex; | |
495 | { | |
496 | register Typeid typeid; | |
497 | register struct symtab *p; | |
498 | register int i, t, strindex; | |
499 | ||
30636230 ML |
500 | if (oldway) { |
501 | /* do nothing */; | |
502 | } else if (gdebug) { | |
2bfe20cf ML |
503 | i = dimtab[szindex + 3]; |
504 | p = &stab[i]; | |
505 | if (p->sname != nil) { | |
506 | strindex = dimtab[p->sizoff + 1]; | |
507 | typeid = typelookup(p->stype, NILINDEX, FORWARD, i); | |
508 | if (typeid == nil) { | |
509 | t = 0; | |
510 | } else { | |
511 | t = typeid->tnum; | |
512 | reentertype(typeid, p->stype, NILINDEX, strindex, NILINDEX); | |
513 | } | |
514 | printf("\t.stabs\t\"%s:T", p->sname); | |
515 | genstruct(p->stype, t, strindex, p->sname, bsize(p)); | |
516 | geninfo(p); | |
517 | } | |
518 | } | |
519 | } | |
520 | ||
521 | pstab(name, type) | |
522 | char *name; | |
523 | int type; | |
524 | { | |
525 | register int i; | |
526 | register char c; | |
30636230 ML |
527 | |
528 | if (!gdebug) { | |
529 | return; | |
530 | } else if (oldway) { | |
531 | old_pstab(name, type); | |
532 | return; | |
533 | } | |
2bfe20cf ML |
534 | /* locctr(PROG); /* .stabs must appear in .text for c2 */ |
535 | #ifdef ASSTRINGS | |
536 | if ( name[0] == '\0') | |
537 | printf("\t.stabn\t"); | |
538 | else | |
539 | #ifndef FLEXNAMES | |
540 | printf("\t.stabs\t\"%.8s\",", name); | |
541 | #else | |
542 | printf("\t.stabs\t\"%s\",", name); | |
543 | #endif | |
544 | #else | |
545 | printf(" .stab "); | |
546 | for(i=0; i<8; i++) | |
547 | if (c = name[i]) printf("'%c,", c); | |
548 | else printf("0,"); | |
549 | #endif | |
550 | printf("0%o,", type); | |
551 | } | |
552 | ||
553 | #ifdef STABDOT | |
554 | pstabdot(type, value) | |
555 | int type; | |
556 | int value; | |
557 | { | |
30636230 ML |
558 | if ( ! gdebug) { |
559 | return; | |
560 | } else if (oldway) { | |
561 | old_pstabdot(type, value); | |
562 | return; | |
563 | } | |
2bfe20cf ML |
564 | /* locctr(PROG); /* .stabs must appear in .text for c2 */ |
565 | printf("\t.stabd\t"); | |
566 | printf("0%o,0,0%o\n",type, value); | |
567 | } | |
568 | #endif | |
569 | ||
570 | extern char NULLNAME[8]; | |
571 | extern int labelno; | |
572 | extern int fdefflag; | |
573 | ||
574 | psline() | |
575 | { | |
576 | static int lastlineno; | |
577 | register char *cp, *cq; | |
578 | register int i; | |
579 | ||
30636230 ML |
580 | if (!gdebug) { |
581 | return; | |
582 | } else if (oldway) { | |
583 | old_psline(); | |
584 | return; | |
585 | } | |
2bfe20cf ML |
586 | |
587 | cq = ititle; | |
588 | cp = ftitle; | |
589 | ||
590 | while ( *cq ) if ( *cp++ != *cq++ ) goto neq; | |
591 | if ( *cp == '\0' ) goto eq; | |
592 | ||
593 | neq: for (i=0; i<100; i++) | |
594 | ititle[i] = '\0'; | |
595 | cp = ftitle; | |
596 | cq = ititle; | |
597 | while ( *cp ) | |
598 | *cq++ = *cp++; | |
599 | *cq = '\0'; | |
600 | *--cq = '\0'; | |
601 | #ifndef FLEXNAMES | |
602 | for ( cp = ititle+1; *(cp-1); cp += 8 ) { | |
603 | pstab(cp, N_SOL); | |
604 | if (gdebug) printf("0,0,LL%d\n", labelno); | |
605 | } | |
606 | #else | |
607 | pstab(ititle+1, N_SOL); | |
608 | if (gdebug) printf("0,0,LL%d\n", labelno); | |
609 | #endif | |
610 | *cq = '"'; | |
611 | printf("LL%d:\n", labelno++); | |
612 | ||
613 | eq: if (lineno == lastlineno) return; | |
614 | lastlineno = lineno; | |
615 | ||
616 | if (fdefflag) { | |
617 | #ifdef STABDOT | |
618 | pstabdot(N_SLINE, lineno); | |
619 | #else | |
620 | pstab(NULLNAME, N_SLINE); | |
621 | printf("0,%d,LL%d\n", lineno, labelno); | |
622 | printf("LL%d:\n", labelno++); | |
623 | #endif | |
624 | } | |
625 | } | |
626 | ||
627 | plcstab(level) | |
628 | int level; | |
629 | { | |
30636230 ML |
630 | if (!gdebug) { |
631 | return; | |
632 | } else if (oldway) { | |
633 | old_plcstab(level); | |
634 | return; | |
635 | } | |
2bfe20cf ML |
636 | #ifdef STABDOT |
637 | pstabdot(N_LBRAC, level); | |
638 | #else | |
639 | pstab(NULLNAME, N_LBRAC); | |
640 | printf("0,%d,LL%d\n", level, labelno); | |
641 | printf("LL%d:\n", labelno++); | |
642 | #endif | |
643 | } | |
644 | ||
645 | prcstab(level) | |
646 | int level; | |
647 | { | |
30636230 ML |
648 | if (!gdebug) { |
649 | return; | |
650 | } else if (oldway) { | |
651 | old_prcstab(level); | |
652 | return; | |
653 | } | |
2bfe20cf ML |
654 | #ifdef STABDOT |
655 | pstabdot(N_RBRAC, level); | |
656 | #else | |
657 | pstab(NULLNAME, N_RBRAC); | |
658 | printf("0,%d,LL%d\n", level, labelno); | |
659 | printf("LL%d:\n", labelno++); | |
660 | #endif | |
661 | } | |
662 | ||
663 | pfstab(sname) | |
664 | char *sname; | |
665 | { | |
666 | register struct symtab *p; | |
667 | ||
668 | if (gdebug) { | |
30636230 ML |
669 | if (oldway) { |
670 | old_pfstab(sname); | |
671 | } else { | |
672 | p = &stab[lookup(sname, 0)]; | |
673 | printf("\t.stabs\t\"%s:", p->sname); | |
674 | putchar((p->sclass == STATIC) ? 'f' : 'F'); | |
675 | gentype(p); | |
676 | geninfo(p); | |
677 | } | |
2bfe20cf ML |
678 | } |
679 | } | |
30636230 ML |
680 | |
681 | /* | |
682 | * Old way of doing things. | |
683 | */ | |
684 | ||
685 | private old_fixarg(p) | |
686 | struct symtab *p; { | |
687 | if (gdebug) { | |
688 | old_pstab(p->sname, N_PSYM); | |
689 | if (gdebug) printf("0,%d,%d\n", p->stype, argoff/SZCHAR); | |
690 | old_poffs(p); | |
691 | } | |
692 | } | |
693 | ||
694 | private old_outstab(p) | |
695 | struct symtab *p; { | |
696 | register TWORD ptype; | |
697 | register char *pname; | |
698 | register char pclass; | |
699 | register int poffset; | |
700 | ||
701 | if (!gdebug) return; | |
702 | ||
703 | ptype = p->stype; | |
704 | pname = p->sname; | |
705 | pclass = p->sclass; | |
706 | poffset = p->offset; | |
707 | ||
708 | if (ISFTN(ptype)) { | |
709 | return; | |
710 | } | |
711 | ||
712 | switch (pclass) { | |
713 | ||
714 | case AUTO: | |
715 | old_pstab(pname, N_LSYM); | |
716 | printf("0,%d,%d\n", ptype, (-poffset)/SZCHAR); | |
717 | old_poffs(p); | |
718 | return; | |
719 | ||
720 | case EXTDEF: | |
721 | case EXTERN: | |
722 | old_pstab(pname, N_GSYM); | |
723 | printf("0,%d,0\n", ptype); | |
724 | old_poffs(p); | |
725 | return; | |
726 | ||
727 | case STATIC: | |
728 | #ifdef LCOMM | |
729 | /* stabLCSYM is 1 during nidcl so we can get stab type right */ | |
730 | old_pstab(pname, stabLCSYM ? N_LCSYM : N_STSYM); | |
731 | #else | |
732 | old_pstab(pname, N_STSYM); | |
733 | #endif | |
734 | if (p->slevel > 1) { | |
735 | printf("0,%d,L%d\n", ptype, poffset); | |
736 | } else { | |
737 | printf("0,%d,%s\n", ptype, exname(pname)); | |
738 | } | |
739 | old_poffs(p); | |
740 | return; | |
741 | ||
742 | case REGISTER: | |
743 | old_pstab(pname, N_RSYM); | |
744 | printf("0,%d,%d\n", ptype, poffset); | |
745 | old_poffs(p); | |
746 | return; | |
747 | ||
748 | case MOS: | |
749 | case MOU: | |
750 | old_pstab(pname, N_SSYM); | |
751 | printf("0,%d,%d\n", ptype, poffset/SZCHAR); | |
752 | old_poffs(p); | |
753 | return; | |
754 | ||
755 | case PARAM: | |
756 | /* parameter stab entries are processed in dclargs() */ | |
757 | return; | |
758 | ||
759 | default: | |
760 | #ifndef FLEXNAMES | |
761 | if (ddebug) printf(" No .stab for %.8s\n", pname); | |
762 | #else | |
763 | if (ddebug) printf(" No .stab for %s\n", pname); | |
764 | #endif | |
765 | ||
766 | } | |
767 | } | |
768 | ||
769 | private old_pstab(name, type) | |
770 | char *name; | |
771 | int type; { | |
772 | register int i; | |
773 | register char c; | |
774 | if (!gdebug) return; | |
775 | /* locctr(PROG); /* .stabs must appear in .text for c2 */ | |
776 | #ifdef ASSTRINGS | |
777 | if ( name[0] == '\0') | |
778 | printf("\t.stabn\t"); | |
779 | else | |
780 | #ifndef FLEXNAMES | |
781 | printf("\t.stabs\t\"%.8s\", ", name); | |
782 | #else | |
783 | printf("\t.stabs\t\"%s\", ", name); | |
784 | #endif | |
785 | #else | |
786 | printf(" .stab "); | |
787 | for(i=0; i<8; i++) | |
788 | if (c = name[i]) printf("'%c,", c); | |
789 | else printf("0,"); | |
790 | #endif | |
791 | printf("0%o,", type); | |
792 | } | |
793 | ||
794 | #ifdef STABDOT | |
795 | private old_pstabdot(type, value) | |
796 | int type; | |
797 | int value; | |
798 | { | |
799 | if ( ! gdebug) return; | |
800 | /* locctr(PROG); /* .stabs must appear in .text for c2 */ | |
801 | printf("\t.stabd\t"); | |
802 | printf("0%o,0,0%o\n",type, value); | |
803 | } | |
804 | #endif | |
805 | ||
806 | private old_poffs(p) | |
807 | register struct symtab *p; { | |
808 | int s; | |
809 | if (!gdebug) return; | |
810 | if ((s = dimtab[p->sizoff]/SZCHAR) > 1) { | |
811 | old_pstab(p->sname, N_LENG); | |
812 | printf("1,0,%d\n", s); | |
813 | } | |
814 | } | |
815 | ||
816 | private old_psline() { | |
817 | static int lastlineno; | |
818 | register char *cp, *cq; | |
819 | register int i; | |
820 | ||
821 | if (!gdebug) return; | |
822 | ||
823 | cq = ititle; | |
824 | cp = ftitle; | |
825 | ||
826 | while ( *cq ) if ( *cp++ != *cq++ ) goto neq; | |
827 | if ( *cp == '\0' ) goto eq; | |
828 | ||
829 | neq: for (i=0; i<100; i++) | |
830 | ititle[i] = '\0'; | |
831 | cp = ftitle; | |
832 | cq = ititle; | |
833 | while ( *cp ) | |
834 | *cq++ = *cp++; | |
835 | *cq = '\0'; | |
836 | *--cq = '\0'; | |
837 | #ifndef FLEXNAMES | |
838 | for ( cp = ititle+1; *(cp-1); cp += 8 ) { | |
839 | old_pstab(cp, N_SOL); | |
840 | if (gdebug) printf("0,0,LL%d\n", labelno); | |
841 | } | |
842 | #else | |
843 | old_pstab(ititle+1, N_SOL); | |
844 | if (gdebug) printf("0,0,LL%d\n", labelno); | |
845 | #endif | |
846 | *cq = '"'; | |
847 | printf("LL%d:\n", labelno++); | |
848 | ||
849 | eq: if (lineno == lastlineno) return; | |
850 | lastlineno = lineno; | |
851 | ||
852 | if (fdefflag) { | |
853 | #ifdef STABDOT | |
854 | old_pstabdot(N_SLINE, lineno); | |
855 | #else | |
856 | old_pstab(NULLNAME, N_SLINE); | |
857 | printf("0,%d,LL%d\n", lineno, labelno); | |
858 | printf("LL%d:\n", labelno++); | |
859 | #endif | |
860 | } | |
861 | } | |
862 | ||
863 | private old_plcstab(level) { | |
864 | if (!gdebug) return; | |
865 | #ifdef STABDOT | |
866 | old_pstabdot(N_LBRAC, level); | |
867 | #else | |
868 | old_pstab(NULLNAME, N_LBRAC); | |
869 | printf("0,%d,LL%d\n", level, labelno); | |
870 | printf("LL%d:\n", labelno++); | |
871 | #endif | |
872 | } | |
873 | ||
874 | private old_prcstab(level) { | |
875 | if (!gdebug) return; | |
876 | #ifdef STABDOT | |
877 | pstabdot(N_RBRAC, level); | |
878 | #else | |
879 | pstab(NULLNAME, N_RBRAC); | |
880 | printf("0,%d,LL%d\n", level, labelno); | |
881 | printf("LL%d:\n", labelno++); | |
882 | #endif | |
883 | } | |
884 | ||
885 | private old_pfstab(sname) | |
886 | char *sname; { | |
887 | if (!gdebug) return; | |
888 | pstab(sname, N_FUN); | |
889 | #ifndef FLEXNAMES | |
890 | printf("0,%d,_%.7s\n", lineno, sname); | |
891 | #else | |
892 | printf("0,%d,_%s\n", lineno, sname); | |
893 | #endif | |
894 | } |