xref: /original-bsd/usr.bin/pascal/src/stab.c (revision 7e7b101a)
1 /* Copyright (c) 1980 Regents of the University of California */
2 
3 #ifndef lint
4 static	char sccsid[] = "@(#)stab.c 2.3 03/15/85";
5 #endif
6 
7     /*
8      *	Procedures to put out symbol table information
9      *	and stabs for separate compilation type checking.
10      *	These use the .stabs, .stabn, and .stabd directives.
11      */
12 
13 #include	"whoami.h"
14 #ifdef	PC
15     /*	and the rest of the file */
16 #   include	"0.h"
17 #   include	"objfmt.h"
18 #   include	"yy.h"
19 #   include	<stab.h>
20 
21     /*
22      *  additional symbol definition for <stab.h>
23      *	that is used by the separate compilation facility --
24      *	eventually, <stab.h> should be updated to include this
25      */
26 
27 #   include	"pstab.h"
28 #   include	"pc.h"
29 
30 
31 #define private static
32 
33 int oldway = 0;
34 
35     /*
36      *	absolute value: line numbers are negative if error recovery.
37      */
38 #define	ABS( x )	( x < 0 ? -x : x )
39 long checksum();
40 
41 /*
42  * Generate information about variables.
43  */
44 
45 stabgvar (p, length, line)
46 struct nl *p;
47 int length, line;
48 {
49     putprintf("	.stabs	\"%s\",0x%x,0,0x%x,0x%x",
50 	0, p->symbol, N_PC, N_PGVAR, ABS(line)
51     );
52     if (oldway != 0) {
53 	oldstabgvar(p->symbol, p2type(p->type), 0, length, line);
54     } else if (opt('g')) {
55 	putprintf("\t.stabs\t\"%s:G", 1, p->symbol);
56 	gentype(p->type);
57 	putprintf("\",0x%x,0,0x%x,0", 0, N_GSYM, length);
58     }
59 }
60 
61 stablvar (p, offset, length)
62 struct nl *p;
63 int offset, length;
64 {
65     int level;
66 
67     level = (p->nl_block & 037);
68     if (oldway != 0) {
69 	oldstablvar(p->symbol, p2type(p->type), level, offset, length);
70     } else if (opt('g')) {
71 	putprintf("\t.stabs\t\"%s:", 1, p->symbol);
72 	gentype(p->type);
73 	putprintf("\",0x%x,0,0x%x,0x%x", 0, N_LSYM, length, offset);
74     }
75 }
76 
77     /*
78      *	global variables
79      */
80 /*ARGSUSED*/
81 oldstabgvar( name , type , offset , length , line )
82     char	*name;
83     int		type;
84     int		offset;
85     int		length;
86     int		line;
87     {
88 	if ( ! opt('g') ) {
89 		return;
90 	}
91 	putprintf( "	.stabs	\"" , 1 );
92 	putprintf( NAMEFORMAT , 1 , (int) name );
93 	putprintf( "\",0x%x,0,0x%x,0" , 0 , N_GSYM , type );
94 	putprintf( "	.stabs	\"" , 1 );
95 	putprintf( NAMEFORMAT , 1 , (int) name );
96 	putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
97 }
98 
99     /*
100      *	local variables
101      */
102 /*ARGSUSED*/
103 oldstablvar( name , type , level , offset , length )
104     char	*name;
105     int		type;
106     int		level;
107     int		offset;
108     int		length;
109     {
110 
111 	if ( ! opt('g') ) {
112 		return;
113 	}
114 	putprintf( "	.stabs	\"" , 1 );
115 	putprintf( NAMEFORMAT , 1 , (int) name );
116 	putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_LSYM , type , -offset );
117 	putprintf( "	.stabs	\"" , 1 );
118 	putprintf( NAMEFORMAT , 1 , (int) name );
119 	putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
120 }
121 
122 
123 stabparam (p, offset, length)
124 struct nl *p;
125 int offset, length;
126 {
127     if (oldway != 0) {
128 	oldstabparam(p->symbol, p2type(p->type), offset, length);
129     } else if (opt('g')) {
130 	putprintf("\t.stabs\t\"%s:", 1, p->symbol);
131 	if (p->class == REF) {
132 	    putprintf("v", 1);
133 	} else {
134 	    putprintf("p", 1);
135 	}
136 	gentype((p->class == FPROC || p->class ==FFUNC) ? p : p->type);
137 	putprintf("\",0x%x,0,0x%x,0x%x", 0, N_PSYM, length, offset);
138     }
139 }
140 
141     /*
142      *	parameters
143      */
144 oldstabparam( name , type , offset , length )
145     char	*name;
146     int		type;
147     int		offset;
148     int		length;
149     {
150 
151 	if ( ! opt('g') ) {
152 		return;
153 	}
154 	putprintf( "	.stabs	\"" , 1 );
155 	putprintf( NAMEFORMAT , 1 , (int) name );
156 	putprintf( "\",0x%x,0,0x%x,0x%x" , 0 , N_PSYM , type , offset );
157 	putprintf( "	.stabs	\"" , 1 );
158 	putprintf( NAMEFORMAT , 1 , (int) name );
159 	putprintf( "\",0x%x,0,0,0x%x" , 0 , N_LENG , length );
160     }
161 
162     /*
163      *	fields
164      */
165 
166     /*
167      *	left brackets
168      *  (dbx handles module-2 without these, so we won't use them either)
169      */
170 stablbrac( level )
171     int	level;
172     {
173 
174 	if ( ! opt('g') || oldway == 0 ) {
175 		return;
176 	}
177 	putprintf( "	.stabd	0x%x,0,0x%x" , 0 , N_LBRAC , level );
178     }
179 
180     /*
181      *	right brackets
182      */
183 stabrbrac( level )
184     int	level;
185     {
186 
187 	if ( ! opt('g') || oldway == 0 ) {
188 		return;
189 	}
190 	putprintf( "	.stabd	0x%x,0,0x%x" , 0 , N_RBRAC , level );
191     }
192 
193 stabfunc (p, name, line, level)
194 struct nl *p;
195 char *name;
196 int line, level;
197 {
198     char extname[BUFSIZ],nestspec[BUFSIZ];
199 
200     if ( level == 1 ) {
201 	if (p->class == FUNC) {
202 	    putprintf("	.stabs	\"%s\",0x%x,0,0x%x,0x%x" ,
203 		0 , name , N_PC , N_PGFUNC , ABS( line )
204 	    );
205 	} else if (p->class == PROC) {
206 	    putprintf("	.stabs	\"%s\",0x%x,0,0x%x,0x%x" ,
207 		0 , name , N_PC , N_PGPROC , ABS( line )
208 	    );
209 	}
210     }
211     if (oldway != 0) {
212 	oldstabfunc(name, p->class, line, level);
213     } else if (opt('g')) {
214 	putprintf("\t.stabs\t\"%s:", 1, name);
215 	if (p->class == FUNC) {
216 	    putprintf("F", 1);
217 	    gentype(p->type);
218 	    putprintf(",", 1);
219 	} else {
220 	    putprintf("P,", 1);
221 	}
222 	sextname(extname, name, level);  /* set extname to entry label */
223 	putprintf("%s,", 1, &(extname[1])); /* remove initial underbar */
224 	snestspec(nestspec, level);
225 	putprintf("%s\",0x%x,0,0,%s", 0, nestspec, N_FUN, extname);
226     }
227 }
228 
229     /*
230      * construct the colon-separated static nesting string into a
231      * caller-supplied buffer
232      */
233 private snestspec(buffer, level)
234     char buffer[];
235     int level;
236 {
237     char *starthere;
238     int i;
239 
240     if (level <= 1) {
241 	buffer[0] = '\0';
242     } else {
243 	starthere = &buffer[0];
244 	for ( i = 1 ; i < level ; i++ ) {
245 	    sprintf(starthere, "%s:", enclosing[i]);
246 	    starthere += strlen(enclosing[i]) + 1;
247 	}
248 	*starthere-- = '\0'; /* remove last colon */
249 	if (starthere >= &buffer[BUFSIZ-1]) {
250 	    panic("snestspec");
251 	}
252     }
253 }
254 
255     /*
256      *	functions
257      */
258 oldstabfunc( name , typeclass , line , level )
259     char	*name;
260     int		typeclass;
261     int		line;
262     long	level;
263     {
264 	char	extname[ BUFSIZ ];
265 
266 	    /*
267 	     *	for sdb
268 	     */
269 	if ( ! opt('g') ) {
270 		return;
271 	}
272 	putprintf( "	.stabs	\"" , 1 );
273 	putprintf( NAMEFORMAT , 1 , (int) name );
274 	sextname( extname , name , (int) level );
275 	putprintf( "\",0x%x,0,0x%x,%s" , 0 , N_FUN , line , (int) extname );
276     }
277 
278     /*
279      *	source line numbers
280      */
281 stabline( line )
282     int	line;
283     {
284 	if ( ! opt('g') ) {
285 		return;
286 	}
287 	putprintf( "	.stabd	0x%x,0,0x%x" , 0 , N_SLINE , ABS( line ) );
288     }
289 
290     /*
291      *	source files get none or more of these:
292      *  one as they are entered,
293      *  and one every time they are returned to from nested #includes
294      */
295 stabsource(filename, firsttime)
296     char	*filename;
297     bool	firsttime;
298 {
299     int		label;
300 
301 	/*
302 	 *	for separate compilation
303 	 */
304     putprintf("	.stabs	\"%s\",0x%x,0,0x%x,0x%x", 0,
305 	    (int) filename, N_PC, N_PSO, N_FLAGCHECKSUM);
306 	/*
307 	 *	for debugger
308 	 */
309     if ( ! opt('g') ) {
310 	    return;
311     }
312     if (oldway != 0) {
313 	label = (int) getlab();
314 	putprintf( "	.stabs	\"" , 1 );
315 	putprintf( NAMEFORMAT , 1 , filename );
316 	putprintf( "\",0x%x,0,0," , 1 , N_SO );
317 	putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label );
318 	putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label );
319 	putprintf( ":" , 0 );
320     } else {
321 	if (firsttime) {
322 	    putprintf( "	.stabs	\"" , 1 );
323 	    putprintf( NAMEFORMAT , 1 , filename );
324 	    putprintf( "\",0x%x,0,0,0" , 0 , N_SO );
325 	}
326     }
327 }
328 
329     /*
330      *	included files get one or more of these:
331      *	one as they are entered by a #include,
332      *	and one every time they are returned to from nested #includes.
333      */
334 stabinclude(filename, firsttime)
335     char	*filename;
336     bool	firsttime;
337 {
338     int		label;
339     long	check;
340 
341 	/*
342 	 *	for separate compilation
343 	 */
344     if (firsttime) {
345 	check = checksum(filename);
346     } else {
347 	check = N_FLAGCHECKSUM;
348     }
349     putprintf("	.stabs	\"%s\",0x%x,0,0x%x,0x%x", 0,
350 	    (int) filename, N_PC, N_PSOL, check);
351 	/*
352 	 *	for sdb
353 	 */
354     if ( ! opt('g') ) {
355 	    return;
356     }
357     if (oldway != 0) {
358 	label = (int) getlab();
359 	putprintf( "	.stabs	\"" , 1 );
360 	putprintf( NAMEFORMAT , 1 , filename );
361 	putprintf( "\",0x%x,0,0," , 1 , N_SOL );
362 	putprintf( PREFIXFORMAT , 0 , LLABELPREFIX , label );
363 	putprintf( PREFIXFORMAT , 1 , LLABELPREFIX , label );
364 	putprintf( ":" , 0 );
365     }
366 }
367 
368     /*
369      *	anyone know a good checksum for ascii files?
370      *	this does a rotate-left and then exclusive-or's in the character.
371      *	also, it avoids returning checksums of 0.
372      *	The rotate is implemented by shifting and adding back the
373      *	sign bit when negative.
374      */
375 long
376 checksum(filename)
377     char	*filename;
378 {
379     FILE		*filep;
380     register int	input;
381     register long	check;
382 
383     filep = fopen(filename, "r");
384     if (filep == NULL) {
385 	perror(filename);
386 	pexit(DIED);
387     }
388     check = 0;
389     while ((input = getc(filep)) != EOF) {
390 	if (check < 0) {
391 	    check <<= 1;
392 	    check += 1;
393 	} else {
394 	    check <<= 1;
395 	}
396 	check ^= input;
397     }
398     (void) fclose(filep);
399     if ((unsigned) check <= N_FLAGCHECKSUM) {
400 	return N_FLAGCHECKSUM + 1;
401     } else {
402 	return check;
403     }
404 }
405 
406 /*
407  * global Pascal symbols :
408  *   labels, types, constants, and external procedure and function names:
409  *   These are used by the separate compilation facility
410  *   to be able to check for disjoint header files.
411  */
412 
413     /*
414      *	global labels
415      */
416 stabglabel( label , line )
417     char	*label;
418     int		line;
419     {
420 
421 	putprintf( "	.stabs	\"%s\",0x%x,0,0x%x,0x%x" , 0
422 		    , (int) label , N_PC , N_PGLABEL , ABS( line ) );
423     }
424 
425     /*
426      *	global constants
427      */
428 stabgconst( const , line )
429     char	*const;
430     int		line;
431     {
432 
433 	    putprintf( "	.stabs	\"%s\",0x%x,0,0x%x,0x%x" , 0
434 			, (int) const , N_PC , N_PGCONST , ABS( line ) );
435     }
436 
437 /*
438  * Generate symbolic information about a constant.
439  */
440 
441 stabconst (c)
442 struct nl *c;
443 {
444     if (opt('g') && oldway == 0) {
445 	putprintf("\t.stabs\t\"%s:c=", 1, c->symbol);
446 	if (c->type == nl + TSTR) {
447 	    putprintf("s'%s'", 1, c->ptr[0]);
448 	} else if (c->type == nl + T1CHAR) {
449 	    putprintf("c%d", 1, c->range[0]);
450 	} else if (isa(c->type, "i")) {
451 	    putprintf("i%d", 1, c->range[0]);
452 	} else if (isa(c->type, "d")) {
453 	    putprintf("r%g", 1, c->real);
454 	} else {
455 	    putprintf("e", 1);
456 	    gentype(c->type);
457 	    putprintf(",%d", 1, c->range[0]);
458 	}
459 	putprintf("\",0x%x,0,0x%x,0x%x", 0, N_LSYM, 0, 0);
460     }
461 }
462 
463 stabgtype (name, type, line)
464 char *name;
465 struct nl *type;
466 int line;
467 {
468     putprintf("	.stabs	\"%s\",0x%x,0,0x%x,0x%x" ,
469 	0, name, N_PC , N_PGTYPE, ABS(line)
470     );
471     if (oldway == 0) {
472 	stabltype(name, type);
473     }
474 }
475 
476 stabltype (name, type)
477 char *name;
478 struct nl *type;
479 {
480     if (opt('g')) {
481 	putprintf("\t.stabs\t\"%s:t", 1, name);
482 	gentype(type);
483 	putprintf("\",0x%x,0,0,0", 0, N_LSYM);
484     }
485 }
486 
487     /*
488      *	external functions and procedures
489      */
490 stabefunc( name , typeclass , line )
491     char	*name;
492     int		typeclass;
493     int		line;
494     {
495 	int	type;
496 
497 	if ( typeclass == FUNC ) {
498 	    type = N_PEFUNC;
499 	} else if ( typeclass == PROC ) {
500 	    type = N_PEPROC;
501 	} else {
502 	    return;
503 	}
504 	putprintf( "	.stabs	\"%s\",0x%x,0,0x%x,0x%x" , 0
505 		    , (int) name , N_PC , type , ABS( line ) );
506     }
507 
508 /*
509  * Generate type information encoded as a string for dbx.
510  * The fwdptrnum field is used only when the type is a pointer
511  * to a type that isn't known when it was entered.  When the
512  * type field is filled for some such tptr, fixfwdtype should
513  * be called to output an equivalencing type definition.
514  */
515 
516 typedef struct TypeDesc *TypeDesc;
517 
518 struct TypeDesc {
519     struct nl *tptr;
520     int tnum;
521     int fwdptrnum;
522     TypeDesc chain;
523 };
524 
525 #define TABLESIZE 2003
526 
527 #define typehash(t) ( ( ((int) t) >> 2 ) % TABLESIZE )
528 
529 private int tcount = 1;
530 private TypeDesc typetable[TABLESIZE];
531 
532 private TypeDesc tdlookup (t)
533 struct nl *t;
534 {
535     register TypeDesc td;
536 
537     td = typetable[typehash(t)];
538     while (td != NIL && td->tptr != t) {
539 	td = td->chain;
540     }
541     return td;
542 }
543 
544 private int typelookup (t)
545 struct nl *t;
546 {
547     register TypeDesc td;
548     int r;
549 
550     td = tdlookup(t);
551     if (td == NIL) {
552 	r = 0;
553     } else {
554 	r = td->tnum;
555     }
556     return r;
557 }
558 
559 private int entertype (type)
560 struct nl *type;
561 {
562     register TypeDesc td;
563     register int i;
564 
565     td = (TypeDesc) malloc(sizeof(struct TypeDesc));
566     td->tptr = type;
567     td->tnum = tcount;
568     td->fwdptrnum = 0;
569     ++tcount;
570     i = typehash(type);
571     td->chain = typetable[i];
572     typetable[i] = td;
573     return td->tnum;
574 }
575 
576 /*
577  * The in_types table currently contains "boolean", "char", "integer",
578  * "real" and "_nil".  (See nl.c for definition.)
579  * The lookup call below will give the TYPE class nl entry for these
580  * types.  In each case except _nil, the type field of that entry is a RANGE
581  * class nl entry for the type.  Sometimes other symbol table entries
582  * point to the TYPE entry (e.g., when there is a range over the base type),
583  * and other entries point to the RANGE entry (e.g., for a variable of the
584  * given type).  We don't really want to distinguish between these uses
585  * in dbx, and since it appears that the RANGE entries are not reused if
586  * a range happens to coincide, we will give the two the same identifying
587  * dbx type number.
588  */
589 
590 private inittypes()
591 {
592     int i;
593     extern char *in_types[];
594     struct nl *p;
595 
596     for (i = 0; in_types[i] != NIL; i++) {
597 	p = lookup(in_types[i]);
598 	if (p != NIL) {
599 	    entertype(p);
600 	    if (p->type != NIL) {
601 		--tcount; /* see comment above */
602 		entertype(p->type);
603 	    }
604 	}
605     }
606 }
607 
608 static genarray (t)
609 struct nl *t;
610 {
611     register struct nl *p;
612 
613     putprintf("a", 1);
614     for (p = t->chain; p != NIL; p = p->chain) {
615 	gentype(p);
616 	putprintf(";", 1);
617     }
618     gentype(t->type);
619 }
620 
621 /*
622  * Really we should walk through ptr[NL_FIELDLIST] for the fields,
623  * and then do the variant tag and fields separately, but dbx
624  * doesn't support this yet.
625  * So, since all the fields of all the variants are on the chain,
626  * we walk through that.  Except that this gives the fields in the
627  * reverse order, so we want to print in reverse order.
628  */
629 
630 static genrecord (t)
631 struct nl *t;
632 {
633     putprintf("s%d", 1, t->value[NL_OFFS]);
634     if (t->chain != NIL) {
635 	genrecfield(t->chain, 1);
636     }
637     putprintf(";", 1);
638 }
639 
640 static genrecfield (t, n)
641 struct nl *t;
642 int n;
643 {
644     if (t->chain != NULL) {
645 	genrecfield(t->chain, n + 1);
646 	if (n % 2 == 0) {
647 	    gencontinue();
648 	}
649     }
650     putprintf("%s:", 1, t->symbol);
651     gentype(t->type);
652     putprintf(",%d,%d;", 1, 8*t->value[NL_OFFS], 8*lwidth(t->type));
653 }
654 
655 static genvarnt (t)
656 struct nl *t;
657 {
658     genrecord(t);
659 }
660 
661 static genptr (t)
662 struct nl *t;
663 {
664     register TypeDesc td;
665 
666     putprintf("*", 1);
667     if (t->type != NIL) {
668 	gentype(t->type);
669     } else {
670 	/*
671 	 * unresolved forward pointer: use tcount to represent what is
672          * begin pointed to, to be defined later
673 	 */
674 	td = tdlookup(t);
675 	if (td == NIL) {
676 	    panic("nil ptr in stab.genptr");
677 	}
678 	td->fwdptrnum = tcount;
679 	putprintf("%d", 1, tcount);
680 	++tcount;
681     }
682 }
683 
684 /*
685  * The type t is a pointer which has just had its type field filled.
686  * We need to generate a type stab saying that the number saved
687  * in t's fwdptrnum is the same as the t->type's number
688  */
689 
690 fixfwdtype (t)
691 struct nl *t;
692 {
693     register TypeDesc td;
694 
695     if (opt('g') && oldway == 0) {
696 	td = tdlookup(t);
697 	if (td != NIL) {
698 	    putprintf("\t.stabs\t\":t%d=", 1, td->fwdptrnum);
699 	    gentype(t->type);
700 	    putprintf("\",0x%x,0,0,0", 0, N_LSYM);
701 	}
702     }
703 }
704 
705 static genenum (t)
706 struct nl *t;
707 {
708     register struct nl *e;
709     register int i;
710 
711     putprintf("e", 1);
712     i = 1;
713     e = t->chain;
714     while (e != NULL) {
715 	if (i > 2) {
716 	    gencontinue();
717 	    i = 0;
718 	}
719 	putprintf("%s:%d,", 1, e->symbol, e->range[0]);
720 	e = e->chain;
721 	++i;
722     }
723     putprintf(";", 1);
724 }
725 
726 static genset (t)
727 struct nl *t;
728 {
729     putprintf("S", 1);
730     gentype(t->type);
731 }
732 
733 static genrange (t)
734 struct nl *t;
735 {
736     putprintf("r", 1);
737     gentype(t->type);
738     putprintf(";%d;%d", 1, t->range[0], t->range[1]);
739 }
740 
741 static genfparam (t)
742 struct nl *t;
743 {
744     struct nl *p;
745     int count;
746 
747     if (t->type != NULL) {
748 	putprintf("f", 1);
749 	gentype(t->type);
750 	putprintf(",", 1);
751     } else {
752 	putprintf("p", 1);
753     }
754     count = 0;
755     for (p = t->ptr[NL_FCHAIN]; p != NULL; p = p->chain) {
756 	++count;
757     }
758     putprintf("%d;", 1, count);
759     for (p = t->ptr[NL_FCHAIN]; p != NULL; p = p->chain) {
760 	gentype(p->type);
761 	putprintf(",%d;", 1, p->class);
762     }
763 }
764 
765 static genfile (t)
766 struct nl *t;
767 {
768     putprintf("d", 1);
769     gentype(t->type);
770 }
771 
772 static gentype (t)
773 struct nl *t;
774 {
775     int id;
776 
777     if (tcount == 1) {
778 	inittypes();
779     }
780     id = typelookup(t);
781     if (id != 0) {
782 	putprintf("%d", 1, id);
783     } else if (t->class == SCAL && t->chain == NULL) {
784 	id = typelookup(t->type);
785 	if (id != 0) {
786 	    putprintf("%d", 1, id);
787 	} else {
788 	    genenum(t->type);
789 	}
790     } else {
791 	id = entertype(t);
792 	putprintf("%d=", 1, id);
793 	switch (t->class) {
794 	    case TYPE:
795 		gentype(t->type);
796 		break;
797 
798 	    case ARRAY:
799 		genarray(t);
800 		break;
801 
802 	    case RECORD:
803 		genrecord(t);
804 		break;
805 
806 	    case VARNT:
807 		genvarnt(t);
808 		break;
809 
810 	    case REF:
811 		gentype(t->type);
812 		break;
813 
814 	    case PTR:
815 		genptr(t);
816 		break;
817 
818 	    case SET:
819 		genset(t);
820 		break;
821 
822 	    case RANGE:
823 		genrange(t);
824 		break;
825 
826 	    case SCAL:
827 		genenum(t);
828 		break;
829 
830 	    case FPROC:
831 	    case FFUNC:
832 		genfparam(t);
833 		break;
834 
835 	    case FILET:
836 	    case PTRFILE:
837 		genfile(t);
838 		break;
839 
840 	    default:
841 		/* This shouldn't happen */
842 		/* Rather than bomb outright, let debugging go on */
843 		warning();
844 		error("Bad type class found in stab");
845 		putprintf("1", 1, t->class);
846 		break;
847 	}
848     }
849 }
850 
851 /*
852  * Continue stab information in a namelist new entry.  This is necessary
853  * to avoid overflowing putprintf's buffer.
854  */
855 
856 static gencontinue ()
857 {
858     putprintf("?\",0x%x,0,0,0", 0, N_LSYM);
859     putprintf("\t.stabs\t\"", 1);
860 }
861 
862 #endif PC
863