/* debug.c -- symbol table output routines for common assembler */ #include #include "mfile1.h" #include "macdefs.h" #include static FILE * outfile = stdout; /* static now, maybe global later */ #define LINENO (lineno-startln+1) /* local line number */ static int startln; /* editor line number of opening { */ static int oldln; /* last line number printed */ int gdebug; /* -g flag */ static char startfn[100]; /* file name of the opening { */ static char fncname[BUFSIZ+1]; /* name of current function */ static int bb_flags[BCSZ]; /* remember whether or not bb ** is needed */ fixdef(p) struct symtab *p; { /* print debugging info * * don't do params, externs, structure names or members * at this time; they are delayed until more information * is known about them */ switch( p->sclass ) { case USTATIC: case EXTERN: case EXTDEF: case STNAME: case UNAME: case ENAME: case MOS: case MOE: case MOU: return; default: if( p->sclass & FIELD ) return; } /* parameters */ if( p->slevel == 1 ) return; /* static externs */ if( p->sclass == STATIC && p->slevel == 0 ) return; prdef(p,0); } prdims( p ) struct symtab *p; { /* print debugging info for dimensions */ int temp, dtemp, dflag; OFFSZ tsize(); dflag = 0; /* need to print dim */ dtemp = p->dimoff; for( temp=p->stype; temp&TMASK; temp = DECREF(temp) ) { /* put out a dimension for each instance of ARY in type word */ if( ISARY(temp) ) { if( !dflag ) { fprintf( outfile, " dim %ld", dimtab[dtemp++] ); dflag = 1; } else fprintf( outfile, ",%ld", dimtab[dtemp++] ); } } if( dflag ) { fputs( ";\tsize\t", outfile ); fprintf( outfile, /*CONFMT*/"%ld", tsize(p->stype, p->dimoff, p->sizoff ) / SZCHAR ); putc( ';', outfile ); } } /* local table of fakes for un-names structures * sizoff for ~ifake is stored in mystrtab[i] */ #define FAKENM 99 /* maximum number of fakenames */ int mystrtab[FAKENM], ifake = 0; struct symtab mytable; char tagname[BUFSIZ] = ""; prdef(p,dsflg) struct symtab *p; int dsflg; { /* print symbol definition pseudos */ TWORD pty, bpty; TWORD chgtype(); char *strname(); int sclass; int saveloc; if ( dsflg || !gdebug ) return; /* translate storage class */ switch( p->sclass ){ case AUTO: sclass = C_AUTO; break; case EXTDEF: case EXTERN: sclass = C_EXT; break; case STATIC: sclass = C_STAT; break; case REGISTER: sclass = blevel==1 ? C_REGPARM : C_REG; break; case ULABEL: case LABEL: sclass = C_LABEL; break; case MOS: sclass = C_MOS; break; case PARAM: sclass = C_ARG; break; case STNAME: sclass = C_STRTAG; break; case MOU: sclass = C_MOU; break; case UNAME: sclass = C_UNTAG; break; case TYPEDEF: sclass = C_TPDEF; break; case ENAME: sclass = C_ENTAG; break; case MOE: sclass = C_MOE; break; default: if( p->sclass & FIELD ) sclass = C_FIELD; else cerror( "bad storage class %d", p->sclass ); break; } /* print a bb symbol if this is the first symbol in the block */ if( blevel > 2 && !bb_flags[blevel] && sclass != C_LABEL ) { fprintf( outfile, " def ~bb; val ~; scl %d; line %d; endef\n", C_BLOCK, LINENO ); bb_flags[blevel] = 1; /* don't let another bb print */ } /* make sure that defs in functions are in text section */ if( blevel > 1 ) saveloc = locctr( PROG ); fprintf( outfile, " def %s;", exname( p->sname ) ); switch( sclass ) { /* print val based on storage class */ case C_AUTO: /* offset in bytes plus savearea */ fprintf( outfile, " val %ld+S%%%d;", p->offset/SZCHAR, ftnno ); break; case C_MOS: case C_MOU: case C_ARG: /* offset in bytes */ fprintf( outfile, " val %ld;", p->offset/SZCHAR ); break; case C_FIELD: case C_MOE: /* offset in bits, or internal value of enum symbol */ fprintf( outfile, " val %ld;", p->offset ); break; case C_REGPARM: case C_REG: /* offset in bytes in savearea for reg vars */ /* actual offset determination is deferred to the asembler */ /* pointer vars in %aN indicated by adding 8 */ fprintf( outfile, " val %ld;", OUTREGNO(p)); break; case C_STAT: case C_LABEL: case C_EXT: /* actual or hidden name, depending on scope */ if( p->slevel != 0 ) { fprintf( outfile, " val "); fprintf( outfile, LABFMT, (int)p->offset ); putc( ';', outfile); } else fprintf( outfile, " val %s;", exname( p->sname ) ); break; default: break; } pty = chgtype(p->stype); /* change type word from new style ** to old */ bpty = BTYPE(p->stype); fprintf( outfile, " scl %d; type 0%o;", sclass, pty ); /* print tag and size info, size only for tags themselves; * don't print if size not known */ if (dimtab[p->sizoff] > 0) switch( sclass ) { case C_STRTAG: case C_UNTAG: case C_ENTAG: fprintf( outfile, " size %ld;", dimtab[p->sizoff] / SZCHAR ); break; default: /* bpty is base type */ if( (bpty == STRTY || bpty == UNIONTY || bpty == ENUMTY) && gdebug ) { char buf[BUFSIZ]; (void) strcpy( buf, strname( p->sizoff ) ); if ( buf[0] == '$' ) buf[0] = '_'; fprintf( outfile, " tag %s;", exname( buf ) ); fprintf( outfile, " size %ld;", dimtab[p->sizoff] / SZCHAR ); } break; } #ifdef FOOBARBLETCH /* print line for block symbols */ if( p->slevel > 2 ) fprintf( outfile, " line %d;", LINENO ); #endif FOOBARBLETCH /* look for dimensions to print */ if( sclass != C_LABEL && gdebug ) prdims( p ); /* size of field is its length in bits */ if( sclass == C_FIELD ) fprintf( outfile, " size %d;", p->sclass & FLDSIZ ); fputs( "\tendef\n", outfile ); if( blevel > 1 ) locctr( saveloc ); } strend( dimst ) int dimst; { /* called at the end of a structure declaration * this routine puts out the structure tag, its members * and an eos. dimst is the index in dimtab of the * structure description */ int member; OFFSZ size; int saveloc; struct symtab *memptr, *tagnm, *strfind(); if( !gdebug ) return; /* set locctr to text */ saveloc = locctr( PROG ); /* set up tagname */ member = dimtab[dimst + 1]; tagnm = strfind(dimst); if( tagnm == NULL ) { /* create a fake if there is no tagname */ /* use the local symbol table */ tagnm = &mytable; if( ifake == FAKENM ) cerror( "fakename table overflow" ); /* generate the fake name and enter into the fake table */ { char buf[BUFSIZ]; sprintf( buf, "~%dfake", ifake ); mytable.sname = savestr( buf ); /* lives forever! */ } mystrtab[ifake++] = dimst; memptr = &stab[dimtab[member]]; /* fix up the fake's class, type, and sizoff based on class of its members */ switch( memptr->sclass ) { case MOS: tagnm->sclass = STNAME; tagnm->stype = STRTY; break; case MOE: tagnm->sclass = ENAME; tagnm->stype = ENUMTY; break; case MOU: tagnm->sclass = UNAME; tagnm->stype = UNIONTY; break; default: if( memptr->sclass & FIELD ){ tagnm->sclass = STNAME; tagnm->stype = STRTY; } else cerror( "can't identify type of fake tagname" ); } tagnm->slevel = 0;; tagnm->sizoff = dimst; } /* print out the structure header */ { char buf[BUFSIZ], *saveit; saveit = tagnm->sname; (void) strncpy( buf, saveit, BUFSIZ - 1 ); buf[BUFSIZ - 1] = '\0'; tagnm->sname = buf; if ( buf[0] == '$' ) buf[0] = '_'; prdef( tagnm, 0 ); tagnm->sname = saveit; } /* print out members */ while( dimtab[member] >= 0 ) { memptr = &stab[dimtab[member++]]; { char buf[BUFSIZ], *saveit; saveit = memptr->sname; (void) strncpy( buf, saveit, BUFSIZ - 1 ); buf[BUFSIZ - 1] = '\0'; memptr->sname = buf; if ( buf[0] == '$' ) buf[0] = '_'; prdef( memptr, 0 ); memptr->sname = saveit; } } /* print eos */ size = dimtab[dimst] / SZCHAR; fprintf( outfile, " def ~eos; val %ld; scl %d;", size, C_EOS ); fprintf( outfile, " tag %s; size %ld; endef\n", exname( tagnm->sname ), size ); /* return to old locctr */ locctr( saveloc ); } struct symtab * strfind( key ) int key; { /* find the structure tag in the symbol table, 0 == not found */ struct symtab *sptr; char spc; for( sptr = stab; sptr < stab + SYMTSZ; ++sptr ) { spc = sptr->sclass; if( (spc == STNAME || spc == ENAME || spc == UNAME ) && sptr->sizoff == key && sptr->stype != TNULL ) return( sptr ); } /* not found */ return( NULL ); } char * strname( key ) int key; { /* return a pointer to the tagname, * the fake table is used if not found by strfind */ int i; struct symtab *tagnm, *strfind(); tagnm = strfind( key ); if( tagnm != NULL ) return( tagnm->sname ); for( i = 0; i < FAKENM; ++i ) if( mystrtab[i] == key ) { sprintf( tagname, "~%dfake", i ); return( tagname ); } cerror( "structure tagname not found" ); return(NULL); } /* chgtype -- change type word from pcc2 internal type to ** old style type for symbol table utilities. ** ** The old and new types are sufficiently similar to obtain the ** old from the new by extracting the basic type, shifting the ** remaining bits right 1, then OR-ing them back with the basic ** type. That will probably not continue to be true. */ /* Define old types */ #define O_TNULL 020 #define O_TVOID 040 #define O_UNDEF 00 #define O_FARG 01 #define O_CHAR 02 #define O_SHORT 03 #define O_INT 04 #define O_LONG 05 #define O_FLOAT 06 #define O_DOUBLE 07 #define O_STRTY 010 #define O_UNIONTY 011 #define O_ENUMTY 012 #define O_MOETY 013 #define O_UCHAR 014 #define O_USHORT 015 #define O_UNSIGNED 016 #define O_ULONG 017 TWORD chgtype(ntype) TWORD ntype; /* new type */ { TWORD btype = BTYPE(ntype); /* get basic type */ TWORD other = ntype & ~((TWORD) BTMASK); /* get remaining bits */ TWORD newtype; /* derived "new" (i.e., old-style) type */ switch ( btype ) /* convert basic type */ { case TNULL: newtype = O_TNULL; break; case FARG: newtype = O_FARG; break; case CHAR: newtype = O_CHAR; break; case SHORT: newtype = O_SHORT; break; case INT: newtype = O_INT; break; case LONG: newtype = O_LONG; break; case FLOAT: newtype = O_FLOAT; break; case DOUBLE: newtype = O_DOUBLE; break; case STRTY: newtype = O_STRTY; break; case UNIONTY: newtype = O_UNIONTY; break; case ENUMTY: newtype = O_ENUMTY; break; case MOETY: newtype = O_MOETY; break; case UCHAR: newtype = O_UCHAR; break; case USHORT: newtype = O_USHORT; break; case UNSIGNED: newtype = O_UNSIGNED; break; case ULONG: newtype = O_ULONG; break; case VOID: newtype = O_TVOID; break; case UNDEF: newtype = O_UNDEF; break; default: cerror("Unknown basic type\n"); } return( (other >> 1) | newtype ); /* return changed type */ } beg_file(){ /* called as the very first thing by the parser to do machine * dependent stuff */ register char * p; register char * s; extern fpe_catch(); /* note: double quotes already in ftitle... */ p = ftitle + strlen( ftitle ) - 2; *(p+1) = '\"'; s = p - 14; /* max name length */ while ( p > s && *p != '"' && *p != '/' ) --p; fprintf( outfile, ".line 1 \"%.15s\n", p + 1 ); fprintf( outfile, "\t.seg\n\tfp := r13\n\tFP := rr12\n"); fprintf( outfile, "\tsp := r15\n\tSP := rr14\n"); /* * Catch floating exceptions generated by the constant * folding code. */ (void) signal( SIGFPE, fpe_catch ); } fpe_catch() { /* * Floating exception generated by constant folding. */ /* "floating point constant folding causes exception" */ uerror( "floating point constant folding causes exception" ); exit(2); } sdbline() { if ( gdebug && lineno != oldln ) { oldln = lineno; /* remember last line no. output */ if ( curloc == PROG && strcmp( startfn, ftitle ) == 0 ) fprintf( outfile, " ln %d\n", LINENO ); } return; } aobeg(){ /* called before removing automatics from stab */ } aocode(p) struct symtab *p; { /* called when automatic p removed from stab */ } aoend(){ /* called after removing all automatics from stab * print eb here if bb printed for this block */ # ifndef NOSYMB if( gdebug && bb_flags[blevel+1] ) { fprintf( outfile, " def ~eb; val ~; scl %d; line %d; endef\n", C_BLOCK, LINENO ); bb_flags[blevel+1] = 0; } # endif } bfdebug( a, n ) int a[]; int n; { register i; register struct symtab *p; /* remember name of current function */ (void) strcpy( fncname, stab[curftn].sname ); /* initialize line number counters */ oldln = startln = lineno; strcpy( startfn, ftitle ); /* do ~bf symbol and defs for parameters * parameters are delayed to here to two reasons: * 1: they appear inside the ~bf - ~ef * 2: the true declarations have been seen */ if ( gdebug ) { int line; fprintf( outfile, " ln 1\n"); line = lineno; /* line number information for sdb */ fprintf( outfile, " def ~bf; val ~; scl %d; line %d; endef\n", C_FCN ,line ); for( i=0; i 1 ) fprintf( outfile, " ln %d\n", LINENO ); } } eobl2dbg() { /* print debug information at lexical end of function */ if ( gdebug ) { fprintf( outfile, "\tdef %s; val ~; scl -1; endef\n", fncname); } return; } /* called at end of job to output debug information */ ejsdb() { }