|
|
1.1 root 1: /* @(#) debug.c: 1.2 2/27/84 */
2: /* debug.c -- symbol table output routines for common assembler */
3:
4: #include <signal.h>
5: #include "mfile1.h"
6: #include "macdefs.h"
7: #include "storclass.h"
8:
9: FILE * outfile = stdout;
10:
11: #define LINENO (lineno-startln+1) /* local line number */
12:
13: static int startln; /* editor line number of opening { */
14: static int oldln; /* last line number printed */
15: int gdebug; /* -g flag (not used) */
16: static char startfn[100]; /* file name of the opening { */
17: static char fncname[BUFSIZ+1]; /* name of current function */
18: static int bb_flags[BCSZ]; /* remember whether or not bb
19: ** is needed
20: */
21:
22: fix1def(p,dsflag)
23: struct symtab *p;
24: int dsflag; /* 0 to permit output */
25: {
26: /* print debugging info
27: *
28: * don't do params, externs, structure names or members
29: * at this time; they are delayed until more information
30: * is known about them
31: */
32:
33: switch( p->sclass ) {
34:
35: case USTATIC:
36: case EXTERN:
37: case EXTDEF:
38: case STNAME:
39: case UNAME:
40: case ENAME:
41: case MOS:
42: case MOE:
43: case MOU:
44: return;
45: default:
46: if( p->sclass & FIELD ) return;
47: }
48:
49: /* parameters */
50: if( p->slevel == 1 ) return;
51:
52: /* static externs */
53: if( p->sclass == STATIC && p->slevel == 0 ) return;
54:
55: prdef(p,dsflag);
56: }
57:
58: prdims( p ) struct symtab *p; {
59: /* print debugging info for dimensions
60: */
61: int temp, dtemp, dflag;
62: OFFSZ tsize();
63:
64: dflag = 0; /* need to print dim */
65: dtemp = p->dimoff;
66:
67: for( temp=p->stype; temp&TMASK; temp = DECREF(temp) ) {
68: /* put out a dimension for each instance of ARY in type word */
69:
70: if( ISARY(temp) ) {
71: if( !dflag ) {
72: fprintf( outfile, " .dim %d", dimtab[dtemp++] );
73: dflag = 1;
74: }
75: else
76: fprintf( outfile, ",%d", dimtab[dtemp++] );
77: }
78: }
79:
80: if( dflag ) {
81: fputs( ";\t.size\t", outfile );
82: fprintf( outfile, /*CONFMT*/"%ld", tsize(p->stype, p->dimoff, p->sizoff ) / SZCHAR );
83: putc( ';', outfile );
84: }
85: }
86:
87: /* local table of fakes for un-names structures
88: * sizoff for .ifake is stored in mystrtab[i]
89: */
90: #define FAKENM 99 /* maximum number of fakenames */
91: int mystrtab[FAKENM], ifake = 0;
92: struct symtab mytable;
93: char tagname[BUFSIZ] = "";
94:
95: prdef(p, mydsflg)
96: struct symtab *p;
97: int mydsflg;
98: {
99: /* print symbol definition pseudos
100: */
101: extern int dsflag; /* the real one */
102: TWORD pty, bpty;
103: TWORD chgtype();
104: char *strname();
105: int sclass;
106: int saveloc;
107:
108: if ( mydsflg )
109: return;
110:
111: /* translate storage class */
112:
113: switch( p->sclass ){
114: case AUTO: sclass = C_AUTO; break;
115: case EXTDEF:
116: case EXTERN: sclass = C_EXT; break;
117: case STATIC: sclass = C_STAT; break;
118: case REGISTER: sclass = blevel==1 ? C_REGPARM : C_REG; break;
119: case ULABEL:
120: case LABEL: sclass = C_LABEL; break;
121: case MOS: sclass = C_MOS; break;
122: case PARAM: sclass = C_ARG; break;
123: case STNAME: sclass = C_STRTAG; break;
124: case MOU: sclass = C_MOU; break;
125: case UNAME: sclass = C_UNTAG; break;
126: case TYPEDEF: sclass = C_TPDEF; break;
127: case ENAME: sclass = C_ENTAG; break;
128: case MOE: sclass = C_MOE; break;
129: default: if( p->sclass & FIELD )
130: sclass = C_FIELD;
131: else
132: cerror( "bad storage class %d", p->sclass );
133: break;
134: }
135:
136: /* print a .bb symbol if this is the first symbol in the block */
137:
138: if( blevel > 2 && !bb_flags[blevel] && sclass != C_LABEL ) {
139: fprintf( outfile, " .def .bb; .val .; .scl %d; .line %d; .endef\n", C_BLOCK, LINENO );
140: bb_flags[blevel] = 1; /* don't let another .bb print */
141: }
142:
143: /* make sure that .defs in functions are in text section */
144: if( blevel > 1 )
145: saveloc = locctr( PROG );
146:
147: fprintf( outfile, " .def %s;", exname( p->sname ) );
148:
149: switch( sclass ) { /* print val based on storage class */
150:
151: case C_AUTO:
152: case C_MOS:
153: case C_MOU:
154: case C_ARG:
155: /* offset in bytes */
156: fprintf( outfile, " .val %d;", p->offset/SZCHAR );
157: break;
158:
159: case C_FIELD:
160: case C_MOE:
161: /* offset in bits, or internal value of enum symbol */
162: fprintf( outfile, " .val %d;", p->offset );
163: break;
164:
165: case C_REGPARM:
166: case C_REG:
167: /* offset in bytes in savearea for reg vars */
168: /* actual offset determination is deferred to the asembler */
169: /* pointer vars in %aN indicated by adding 8 */
170: fprintf( outfile, " .val %d;", OUTREGNO(p));
171: break;
172:
173: case C_STAT:
174: case C_LABEL:
175: case C_EXT:
176: /* actual or hidden name, depending on scope */
177: if( p->slevel != 0 )
178: {
179: fprintf( outfile, " .val ");
180: fprintf( outfile, LABFMT, p->offset );
181: putc( ';', outfile);
182: }
183: else
184: fprintf( outfile, " .val %s;",
185: exname( p->sname ) );
186: break;
187:
188: default:
189: break;
190: }
191:
192: pty = chgtype(p->stype); /* change type word from new style
193: ** to old
194: */
195: bpty = BTYPE(p->stype);
196: fprintf( outfile, " .scl %d; .type 0%o;", sclass, pty );
197:
198: /* print tag and size info, size only for tags themselves;
199: * don't print if size not known
200: */
201:
202: if (dimtab[p->sizoff] > 0)
203: switch( sclass ) {
204:
205: case C_STRTAG:
206: case C_UNTAG:
207: case C_ENTAG:
208: fprintf( outfile, " .size %d;", (unsigned)dimtab[p->sizoff] / SZCHAR );
209: break;
210:
211: default: /* bpty is base type */
212: /* check the real dsflag here--don't want */
213: /* to put out a .tag for a function when */
214: /* the structure hasn't been .def'ed */
215: if( (bpty == STRTY || bpty == UNIONTY || bpty == ENUMTY) && !dsflag )
216: {
217: char buf[BUFSIZ];
218:
219: (void) strcpy( buf, strname( p->sizoff ) );
220: if ( buf[0] == '$' )
221: buf[0] = '_';
222: fprintf( outfile, " .tag %s;",
223: exname( buf ) );
224: fprintf( outfile, " .size %d;",
225: (unsigned) dimtab[p->sizoff] / SZCHAR );
226: }
227: break;
228: }
229:
230: /* print line for block symbols */
231:
232: if( p->slevel > 2 )
233: fprintf( outfile, " .line %d;", LINENO );
234:
235: /* look for dimensions to print */
236:
237: if( sclass != C_LABEL && !mydsflg )
238: prdims( p );
239:
240: /* size of field is its length in bits */
241:
242: if( sclass == C_FIELD )
243: fprintf( outfile, " .size %d;", p->sclass & FLDSIZ );
244:
245: fputs( "\t.endef\n", outfile );
246: if( blevel > 1 )
247: locctr( saveloc );
248: }
249:
250: str1end( dimst, dsflag )
251: int dimst;
252: int dsflag; /* 0 to enable output */
253: {
254: /* called at the end of a structure declaration
255: * this routine puts out the structure tag, its members
256: * and an eos. dimst is the index in dimtab of the
257: * structure description
258: */
259: int member, size, saveloc;
260: struct symtab *memptr, *tagnm, *strfind();
261:
262: if( dsflag ) return;
263:
264: /* set locctr to text */
265: saveloc = locctr( PROG );
266:
267: /* set up tagname */
268: member = dimtab[dimst + 1];
269: tagnm = strfind(dimst);
270:
271: if( tagnm == NULL ) {
272: /* create a fake if there is no tagname */
273: /* use the local symbol table */
274: tagnm = &mytable;
275: if( ifake == FAKENM )
276: cerror( "fakename table overflow" );
277:
278: /* generate the fake name and enter into the fake table */
279: {
280: char buf[BUFSIZ];
281:
282: sprintf( buf, ".%dfake", ifake );
283: mytable.sname = savestr( buf ); /* lives forever! */
284: }
285: mystrtab[ifake++] = dimst;
286: memptr = &stab[dimtab[member]];
287:
288: /* fix up the fake's class, type, and sizoff based on class of its members */
289: switch( memptr->sclass ) {
290: case MOS:
291: tagnm->sclass = STNAME;
292: tagnm->stype = STRTY;
293: break;
294: case MOE:
295: tagnm->sclass = ENAME;
296: tagnm->stype = ENUMTY;
297: break;
298: case MOU:
299: tagnm->sclass = UNAME;
300: tagnm->stype = UNIONTY;
301: break;
302: default:
303: if( memptr->sclass & FIELD ){
304: tagnm->sclass = STNAME;
305: tagnm->stype = STRTY;
306: }
307: else
308: cerror( "can't identify type of fake tagname" );
309: }
310: tagnm->slevel = 0;;
311: tagnm->sizoff = dimst;
312: }
313:
314: /* print out the structure header */
315: {
316: char buf[BUFSIZ], *saveit;
317:
318: saveit = tagnm->sname;
319: (void) strncpy( buf, saveit, BUFSIZ - 1 );
320: buf[BUFSIZ - 1] = '\0';
321: tagnm->sname = buf;
322: if ( buf[0] == '$' )
323: buf[0] = '_';
324: prdef( tagnm, 0 );
325: tagnm->sname = saveit;
326: }
327:
328: /* print out members */
329: while( dimtab[member] >= 0 ) {
330: memptr = &stab[dimtab[member++]];
331: {
332: char buf[BUFSIZ], *saveit;
333:
334: saveit = memptr->sname;
335: (void) strncpy( buf, saveit, BUFSIZ - 1 );
336: buf[BUFSIZ - 1] = '\0';
337: memptr->sname = buf;
338: if ( buf[0] == '$' )
339: buf[0] = '_';
340: prdef( memptr, 0 );
341: memptr->sname = saveit;
342: }
343: }
344:
345: /* print eos */
346: size = (unsigned)dimtab[dimst] / SZCHAR;
347: fprintf( outfile, " .def .eos; .val %d; .scl %d;", size, C_EOS );
348: fprintf( outfile, " .tag %s; .size %d; .endef\n",
349: exname( tagnm->sname ), size );
350:
351: /* return to old locctr */
352: locctr( saveloc );
353: }
354:
355: struct symtab *
356: strfind( key ) int key; {
357: /* find the structure tag in the symbol table, 0 == not found
358: */
359: struct symtab *sptr;
360: char spc;
361: for( sptr = stab; sptr < stab + SYMTSZ; ++sptr ) {
362: spc = sptr->sclass;
363: if( (spc == STNAME || spc == ENAME || spc == UNAME ) && sptr->sizoff == key && sptr->stype != TNULL )
364: return( sptr );
365: }
366: /* not found */
367: return( NULL );
368: }
369:
370: char *
371: strname( key ) int key; {
372: /* return a pointer to the tagname,
373: * the fake table is used if not found by strfind
374: */
375: int i;
376: struct symtab *tagnm, *strfind();
377: tagnm = strfind( key );
378: if( tagnm != NULL )
379: return( tagnm->sname );
380:
381: for( i = 0; i < FAKENM; ++i )
382: if( mystrtab[i] == key ) {
383: sprintf( tagname, ".%dfake", i );
384: return( tagname );
385: }
386:
387: cerror( "structure tagname not found" );
388: return(NULL);
389: }
390:
391: /* chgtype -- change type word from pcc2 internal type to
392: ** old style type for symbol table utilities.
393: **
394: ** The old and new types are sufficiently similar to obtain the
395: ** old from the new by extracting the basic type, shifting the
396: ** remaining bits right 1, then OR-ing them back with the basic
397: ** type. That will probably not continue to be true.
398: */
399:
400: /* Define old types */
401:
402: #define O_TNULL 020
403: #define O_TVOID 040
404: #define O_UNDEF 00
405: #define O_FARG 01
406: #define O_CHAR 02
407: #define O_SHORT 03
408: #define O_INT 04
409: #define O_LONG 05
410: #define O_FLOAT 06
411: #define O_DOUBLE 07
412: #define O_STRTY 010
413: #define O_UNIONTY 011
414: #define O_ENUMTY 012
415: #define O_MOETY 013
416: #define O_UCHAR 014
417: #define O_USHORT 015
418: #define O_UNSIGNED 016
419: #define O_ULONG 017
420:
421: TWORD
422: chgtype(ntype)
423: TWORD ntype; /* new type */
424: {
425: TWORD btype = BTYPE(ntype); /* get basic type */
426: TWORD other = ntype & ~((TWORD) BTMASK);
427: /* get remaining bits */
428:
429: TWORD newtype; /* derived "new" (i.e., old-style) type */
430:
431: switch ( btype ) /* convert basic type */
432: {
433: case TNULL: newtype = O_TNULL; break;
434: case FARG: newtype = O_FARG; break;
435: case CHAR: newtype = O_CHAR; break;
436: case SHORT: newtype = O_SHORT; break;
437: case INT: newtype = O_INT; break;
438: case LONG: newtype = O_LONG; break;
439: case FLOAT: newtype = O_FLOAT; break;
440: case DOUBLE: newtype = O_DOUBLE; break;
441: case STRTY: newtype = O_STRTY; break;
442: case UNIONTY: newtype = O_UNIONTY; break;
443: case ENUMTY: newtype = O_ENUMTY; break;
444: case MOETY: newtype = O_MOETY; break;
445: case UCHAR: newtype = O_UCHAR; break;
446: case USHORT: newtype = O_USHORT; break;
447: case UNSIGNED: newtype = O_UNSIGNED; break;
448: case ULONG: newtype = O_ULONG; break;
449: case VOID: newtype = O_TVOID; break;
450: case UNDEF: newtype = O_UNDEF; break;
451: default: cerror("Unknown basic type\n");
452: }
453: return( (other >> 1) | newtype ); /* return changed type */
454: }
455:
456:
457: sdbln1(dlflag)
458: int dlflag; /* 0 to allow printing */
459: {
460: if ( !dlflag && lineno != oldln )
461: {
462: oldln = lineno; /* remember last line no. output */
463: if ( curloc == PROG && strcmp( startfn, ftitle ) == 0 )
464: fprintf( outfile, " .ln %d\n", LINENO );
465: }
466: return;
467: }
468:
469:
470: aobeg(){
471: /* called before removing automatics from stab
472: */
473: #if defined(M32B) && defined(IMPREGAL)
474: raftn();
475: #endif
476: }
477:
478: aocode(p) struct symtab *p; {
479: /* called when automatic p removed from stab
480: */
481: }
482:
483: aoend1(dsflag)
484: int dsflag; /* 0 to allow printing */
485: {
486: /* called after removing all automatics from stab
487: * print .eb here if .bb printed for this block
488: */
489: # ifndef NOSYMB
490: if( !dsflag && bb_flags[blevel] ) {
491: fprintf( outfile, " .def .eb; .val .; .scl %d; .line %d; .endef\n", C_BLOCK, LINENO );
492: bb_flags[blevel] = 0;
493: }
494: # endif
495: }
496:
497:
498: bfdebug( a, n, dsflag )
499: int a[];
500: int n;
501: int dsflag; /* 0 to allow extra output */
502: {
503: register i;
504: register struct symtab *p;
505:
506: /* remember name of current function */
507:
508: (void) strcpy( fncname, stab[curftn].sname );
509:
510: /* initialize line number counters */
511:
512: oldln = startln = lineno;
513: strcpy( startfn, ftitle );
514:
515: /* do .bf symbol and defs for parameters
516: * parameters are delayed to here to two reasons:
517: * 1: they appear inside the .bf - .ef
518: * 2: the true declarations have been seen
519: */
520: if (!dsflag)
521: {
522: int line;
523:
524: fprintf( outfile, " .ln 1\n");
525: line = lineno; /* line number information for sdb */
526: fprintf( outfile, " .def .bf; .val .; .scl %d; .line %d; .endef\n", C_FCN ,line );
527: for( i=0; i<n; ++i ) {
528: p = &stab[a[i]];
529: prdef(p,0);
530: }
531: }
532: }
533:
534: /* output end of function debugging information */
535:
536: efdebug()
537: {
538: /* print end-of-function pseudo and its line number */
539:
540: fprintf( outfile, " .def .ef; .val .; .scl %d; .line %d; .endef\n", C_FCN, LINENO );
541: if( LINENO > 1 )
542: fprintf( outfile, " .ln %d\n", LINENO );
543: }
544:
545: eobl2dbg()
546: {
547: /* print debug information at lexical end of function */
548:
549: fprintf( outfile, "\t.def %s; .val .; .scl -1; .endef\n", fncname);
550: return;
551: }
552:
553:
554: /* called at end of job to output debug information */
555: ejsdb()
556: {
557: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.