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