xref: /original-bsd/usr.bin/f77/pass1.tahoe/stab.c (revision b8be84b8)
1*b8be84b8Sbostic /*-
2*b8be84b8Sbostic  * Copyright (c) 1980 The Regents of the University of California.
3*b8be84b8Sbostic  * All rights reserved.
4*b8be84b8Sbostic  *
5*b8be84b8Sbostic  * %sccs.include.proprietary.c%
60fd3c7a0Sbostic  */
70fd3c7a0Sbostic 
80fd3c7a0Sbostic #ifndef lint
9*b8be84b8Sbostic static char sccsid[] = "@(#)stab.c	5.3 (Berkeley) 04/12/91";
10*b8be84b8Sbostic #endif /* not lint */
110fd3c7a0Sbostic 
120fd3c7a0Sbostic /*
130fd3c7a0Sbostic  * stab.c
140fd3c7a0Sbostic  *
150fd3c7a0Sbostic  * Symbolic debugging info interface for the f77 compiler.
160fd3c7a0Sbostic  *
170fd3c7a0Sbostic  * Here we generate pseudo-ops that cause the assembler to put
180fd3c7a0Sbostic  * symbolic debugging information into the object file.
190fd3c7a0Sbostic  *
200fd3c7a0Sbostic  * University of Utah CS Dept modification history:
210fd3c7a0Sbostic  *
220fd3c7a0Sbostic  * $Log:	stab.c,v $
230fd3c7a0Sbostic  * Revision 1.2  85/02/02  01:30:09  donn
240fd3c7a0Sbostic  * Don't put the 'program' name into the file; it only confuses dbx, sigh.
250fd3c7a0Sbostic  *
260fd3c7a0Sbostic  */
270fd3c7a0Sbostic 
280fd3c7a0Sbostic #include "defs.h"
290fd3c7a0Sbostic 
300fd3c7a0Sbostic #include <sys/types.h>
310fd3c7a0Sbostic #include <a.out.h>
320fd3c7a0Sbostic #include <stab.h>
330fd3c7a0Sbostic 
340fd3c7a0Sbostic #define public
350fd3c7a0Sbostic #define private static
360fd3c7a0Sbostic #define and &&
370fd3c7a0Sbostic #define or ||
380fd3c7a0Sbostic #define not !
390fd3c7a0Sbostic #define div /
400fd3c7a0Sbostic #define mod %
410fd3c7a0Sbostic #define nil 0
420fd3c7a0Sbostic 
430fd3c7a0Sbostic typedef enum { false, true } Boolean;
440fd3c7a0Sbostic 
450fd3c7a0Sbostic static char asmline[128];
460fd3c7a0Sbostic int len;
470fd3c7a0Sbostic extern char *malloc();
480fd3c7a0Sbostic 
prstab(s,code,type,loc)490fd3c7a0Sbostic prstab(s, code, type, loc)
500fd3c7a0Sbostic char *s, *loc;
510fd3c7a0Sbostic int code, type;
520fd3c7a0Sbostic {
530fd3c7a0Sbostic     char *locout;
540fd3c7a0Sbostic 
550fd3c7a0Sbostic     if (sdbflag) {
560fd3c7a0Sbostic 	locout = (loc == nil) ? "0" : loc;
570fd3c7a0Sbostic 	if (s == nil) {
580fd3c7a0Sbostic 	    sprintf(asmline, "\t.stabn\t0x%x,0,0x%x,%s\n", code, type, locout);
590fd3c7a0Sbostic 	} else {
600fd3c7a0Sbostic 	    sprintf(asmline, "\t.stabs\t\"%s\",0x%x,0,0x%x,%s\n", s, code, type,
610fd3c7a0Sbostic 		locout);
620fd3c7a0Sbostic 	}
630fd3c7a0Sbostic         p2pass( asmline );
640fd3c7a0Sbostic     }
650fd3c7a0Sbostic }
660fd3c7a0Sbostic 
filenamestab(s)670fd3c7a0Sbostic filenamestab(s)
680fd3c7a0Sbostic char *s;
690fd3c7a0Sbostic {
700fd3c7a0Sbostic    sprintf(asmline,"\t.stabs\t\"%s\",0x%x,0,0,0\n", s, N_SO);
710fd3c7a0Sbostic    p2pass( asmline );
720fd3c7a0Sbostic }
730fd3c7a0Sbostic 
linenostab(lineno)740fd3c7a0Sbostic linenostab(lineno)
750fd3c7a0Sbostic int lineno;
760fd3c7a0Sbostic {
770fd3c7a0Sbostic    sprintf(asmline,"\t.stabd\t0x%x,0,%d\n", N_SLINE, lineno);
780fd3c7a0Sbostic    p2pass( asmline );
790fd3c7a0Sbostic }
800fd3c7a0Sbostic 
810fd3c7a0Sbostic /*
820fd3c7a0Sbostic  * Generate information for an entry point
830fd3c7a0Sbostic  */
840fd3c7a0Sbostic 
entrystab(p,class)850fd3c7a0Sbostic public entrystab(p,class)
860fd3c7a0Sbostic register struct Entrypoint *p;
870fd3c7a0Sbostic int class;
880fd3c7a0Sbostic {
890fd3c7a0Sbostic int et;
900fd3c7a0Sbostic Namep q;
910fd3c7a0Sbostic 
920fd3c7a0Sbostic   switch(class) {
930fd3c7a0Sbostic     case CLMAIN:
940fd3c7a0Sbostic         et=writestabtype(TYSUBR);
950fd3c7a0Sbostic 	sprintf(asmline, "\t.stabs\t\"MAIN:F%2d\",0x%x,0,0,L%d\n",
960fd3c7a0Sbostic 				et,N_FUN,p->entrylabel);
970fd3c7a0Sbostic 	p2pass(asmline);
980fd3c7a0Sbostic 	break;
990fd3c7a0Sbostic 
1000fd3c7a0Sbostic      case CLBLOCK:     /* May need to something with block data LATER */
1010fd3c7a0Sbostic 	break;
1020fd3c7a0Sbostic 
1030fd3c7a0Sbostic      default :
1040fd3c7a0Sbostic  	if( (q=p->enamep) == nil) fatal("entrystab has no nameblock");
1050fd3c7a0Sbostic 	sprintf(asmline, "\t.stabs\t\"%s:F", varstr(VL,q->varname));
1060fd3c7a0Sbostic 	len = strlen(asmline);
1070fd3c7a0Sbostic 	/* when insufficient information is around assume TYSUBR; enddcl
1080fd3c7a0Sbostic 	   will fill this in*/
1090fd3c7a0Sbostic 	if(q->vtype == TYUNKNOWN || (q->vtype == TYCHAR && q->vleng == nil) ){
1100fd3c7a0Sbostic            sprintf(asmline+len, "%2d", writestabtype(TYSUBR));
1110fd3c7a0Sbostic  	}
1120fd3c7a0Sbostic         else addtypeinfo(q);
1130fd3c7a0Sbostic 	len += strlen(asmline+len);
1140fd3c7a0Sbostic 	sprintf(asmline+len, "\",0x%x,0,0,L%d\n",N_FUN,p->entrylabel);
1150fd3c7a0Sbostic 	p2pass(asmline);
1160fd3c7a0Sbostic         break;
1170fd3c7a0Sbostic    }
1180fd3c7a0Sbostic }
1190fd3c7a0Sbostic 
1200fd3c7a0Sbostic /*
1210fd3c7a0Sbostic  * Generate information for a symbol table (name block ) entry.
1220fd3c7a0Sbostic  */
1230fd3c7a0Sbostic 
namestab(sym)1240fd3c7a0Sbostic public namestab(sym)
1250fd3c7a0Sbostic Namep sym;
1260fd3c7a0Sbostic {
1270fd3c7a0Sbostic     register Namep p;
1280fd3c7a0Sbostic     char *varname, *classname;
1290fd3c7a0Sbostic     Boolean ignore;
1300fd3c7a0Sbostic     int vartype;
1310fd3c7a0Sbostic 
1320fd3c7a0Sbostic 	ignore = false;
1330fd3c7a0Sbostic 	p = sym;
1340fd3c7a0Sbostic 	if(!p->vdcldone) return;
1350fd3c7a0Sbostic 	vartype = p->vtype;
1360fd3c7a0Sbostic 	varname = varstr(VL, p->varname);
1370fd3c7a0Sbostic 	switch (p->vclass) {
1380fd3c7a0Sbostic 	    case CLPARAM:	/* parameter (constant) */
1390fd3c7a0Sbostic 		classname = "c";
1400fd3c7a0Sbostic 		break;
1410fd3c7a0Sbostic 
1420fd3c7a0Sbostic 	    case CLVAR:		/* variable */
1430fd3c7a0Sbostic 	    case CLUNKNOWN:
1440fd3c7a0Sbostic  		if(p->vstg == STGARG) classname = "v";
1450fd3c7a0Sbostic     		else classname = "V";
1460fd3c7a0Sbostic 		break;
1470fd3c7a0Sbostic 
1480fd3c7a0Sbostic 	    case CLMAIN:	/* main program */
1490fd3c7a0Sbostic 	    case CLENTRY:	/* secondary entry point */
1500fd3c7a0Sbostic 	    case CLBLOCK:       /* block data name*/
1510fd3c7a0Sbostic 	    case CLPROC:	/* external or function or subroutine */
1520fd3c7a0Sbostic 		ignore = true;  /* these are put out by entrystab */
1530fd3c7a0Sbostic 		break;
1540fd3c7a0Sbostic 
1550fd3c7a0Sbostic 
1560fd3c7a0Sbostic 	}
1570fd3c7a0Sbostic 	if (not ignore) {
1580fd3c7a0Sbostic 	    sprintf(asmline, "\t.stabs\t\"%s:%s", varname, classname);
1590fd3c7a0Sbostic 	    len = strlen(asmline);
1600fd3c7a0Sbostic             addtypeinfo(p);
1610fd3c7a0Sbostic 	    len += strlen(asmline+len);
1620fd3c7a0Sbostic 	    switch(p->vstg) {
1630fd3c7a0Sbostic 
1640fd3c7a0Sbostic 	      case STGUNKNOWN :
1650fd3c7a0Sbostic 	      case STGCONST :
1660fd3c7a0Sbostic 	      case STGEXT :
1670fd3c7a0Sbostic 	      case STGINTR :
1680fd3c7a0Sbostic 	      case STGSTFUNCT :
1690fd3c7a0Sbostic 	      case STGLENG :
1700fd3c7a0Sbostic 	      case STGNULL :
1710fd3c7a0Sbostic 	      case STGREG :
1720fd3c7a0Sbostic 	      case STGINIT :
1730fd3c7a0Sbostic 	          sprintf(asmline+len,
1740fd3c7a0Sbostic 		  "\",0x%x,0,0,0 /* don't know how to calc loc for stg %d*/ \n",
1750fd3c7a0Sbostic 			       N_LSYM,p->vstg);
1760fd3c7a0Sbostic 		  break;
1770fd3c7a0Sbostic 
1780fd3c7a0Sbostic 	      case STGARG :
1790fd3c7a0Sbostic 		  sprintf(asmline+len,"\",0x%x,0,0,%d \n",
1800fd3c7a0Sbostic 			      N_PSYM,p->vardesc.varno + ARGOFFSET );
1810fd3c7a0Sbostic 		  break;
1820fd3c7a0Sbostic 
1830fd3c7a0Sbostic 	      case STGCOMMON :
1840fd3c7a0Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,%d\n",
1850fd3c7a0Sbostic 		       N_GSYM, p->voffset);
1860fd3c7a0Sbostic 		  break;
1870fd3c7a0Sbostic 
1880fd3c7a0Sbostic 	      case STGBSS :
1890fd3c7a0Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,v.%d\n",
1900fd3c7a0Sbostic 		     	 (p->inlcomm ? N_LCSYM : N_STSYM),
1910fd3c7a0Sbostic                          p->vardesc.varno);
1920fd3c7a0Sbostic 		  break;
1930fd3c7a0Sbostic 
1940fd3c7a0Sbostic 	      case STGEQUIV :
1950fd3c7a0Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,%s + %d \n",
1960fd3c7a0Sbostic 		     	 (p->inlcomm ? N_LCSYM : N_STSYM) ,
1970fd3c7a0Sbostic                          memname(STGEQUIV,p->vardesc.varno),(p->voffset)) ;
1980fd3c7a0Sbostic 		  break;
1990fd3c7a0Sbostic 
2000fd3c7a0Sbostic 	      case STGAUTO :
2010fd3c7a0Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,-%d \n",
2020fd3c7a0Sbostic 		     	N_LSYM, p->voffset);
2030fd3c7a0Sbostic 
2040fd3c7a0Sbostic 	    }
2050fd3c7a0Sbostic 	    p2pass(asmline);
2060fd3c7a0Sbostic 	}
2070fd3c7a0Sbostic }
2080fd3c7a0Sbostic 
2090fd3c7a0Sbostic static typenum[NTYPES]; /* has the given type already been defined ?*/
2100fd3c7a0Sbostic 
writestabtype(type)2110fd3c7a0Sbostic private writestabtype(type)
2120fd3c7a0Sbostic int type;
2130fd3c7a0Sbostic {
2140fd3c7a0Sbostic  char asmline[130];
2150fd3c7a0Sbostic  static char *typename[NTYPES] =
2160fd3c7a0Sbostic  { "unknown", "addr","integer*2", "integer", "real", "double precision",
2170fd3c7a0Sbostic    "complex", "double complex", "logical", "char", "void", "error" };
2180fd3c7a0Sbostic 
2190fd3c7a0Sbostic  static int typerange[NTYPES] = { 0, 3, 2, 3, 4, 5, 6, 7, 3, 9, 10, 11 };
2200fd3c7a0Sbostic 
2210fd3c7a0Sbostic  /* compare with typesize[] in init.c */
2220fd3c7a0Sbostic  static int typebounds[2] [NTYPES] ={
2230fd3c7a0Sbostic  /* "unknown", "addr","integer*2", "integer",    "real", "double precision", */
2240fd3c7a0Sbostic     { 0      ,   0   ,   -32768,    -2147483648,   4,       8,
2250fd3c7a0Sbostic  /* "complex", "double complex", "logical", "char", "void", "error" }; */
2260fd3c7a0Sbostic       8,         16,               0,        0,       0,          0 },
2270fd3c7a0Sbostic  /* "unknown", "addr","integer*2", "integer",    "real", "double precision", */
2280fd3c7a0Sbostic     { 0  ,       -1,      32767,    2147483647,   0,         0,
2290fd3c7a0Sbostic  /* "complex", "double complex", "logical", "char", "void", "error" }; */
2300fd3c7a0Sbostic       0,         0,               1,        127,       0,          0 }
2310fd3c7a0Sbostic  };
2320fd3c7a0Sbostic 
2330fd3c7a0Sbostic 
2340fd3c7a0Sbostic  if( type < 0 || type > NTYPES) badtype("writestabtype",type);
2350fd3c7a0Sbostic 
2360fd3c7a0Sbostic     if (typenum[type]) return(typenum[type]);
2370fd3c7a0Sbostic     typenum[type] = type;
2380fd3c7a0Sbostic     sprintf(asmline, "\t.stabs\t\"%s:t%d=r%d;%ld;%ld;\",0x%x,0,0,0 \n",
2390fd3c7a0Sbostic 	typename[type], type, typerange[type], typebounds[0][type],
2400fd3c7a0Sbostic         typebounds[1][type], N_GSYM) ;
2410fd3c7a0Sbostic     p2pass(asmline);
2420fd3c7a0Sbostic     return(typenum[type]);
2430fd3c7a0Sbostic }
2440fd3c7a0Sbostic 
2450fd3c7a0Sbostic 
getbasenum(p)2460fd3c7a0Sbostic private getbasenum(p)
2470fd3c7a0Sbostic Namep p;
2480fd3c7a0Sbostic {
2490fd3c7a0Sbostic 
2500fd3c7a0Sbostic   int t;
2510fd3c7a0Sbostic   t = p->vtype;
2520fd3c7a0Sbostic   if( t < TYSHORT || t > TYSUBR)
2530fd3c7a0Sbostic   dclerr("can't get dbx basetype information",p);
2540fd3c7a0Sbostic 
2550fd3c7a0Sbostic   if (p->vtype == TYCHAR || p->vdim != nil ) writestabtype(TYINT);
2560fd3c7a0Sbostic   return(writestabtype(t));
2570fd3c7a0Sbostic }
2580fd3c7a0Sbostic 
2590fd3c7a0Sbostic /*
2600fd3c7a0Sbostic  * Generate debugging information for the given type of the given symbol.
2610fd3c7a0Sbostic  */
2620fd3c7a0Sbostic 
addtypeinfo(sym)2630fd3c7a0Sbostic private addtypeinfo(sym)
2640fd3c7a0Sbostic Namep sym;
2650fd3c7a0Sbostic {
2660fd3c7a0Sbostic     Namep p;
2670fd3c7a0Sbostic     int i,tnum;
2680fd3c7a0Sbostic     char lb[20],ub[20];
2690fd3c7a0Sbostic 
2700fd3c7a0Sbostic     p = sym;
2710fd3c7a0Sbostic     if (p->tag != TNAME) badtag("addtypeinfo",p->tag);
2720fd3c7a0Sbostic 
2730fd3c7a0Sbostic     tnum = getbasenum(p);
2740fd3c7a0Sbostic     if(p->vdim != (struct Dimblock *) ENULL) {
2750fd3c7a0Sbostic 
2760fd3c7a0Sbostic       for (i = p->vdim->ndim-1; i >=0 ; --i) {
2770fd3c7a0Sbostic          if(p->vdim->dims[i].lbaddr == ENULL) {
278bf48e50dSbostic 	      sprintf(lb,"%d", p->vdim->dims[i].lb->constblock.constant.ci);
2790fd3c7a0Sbostic 	 }
2800fd3c7a0Sbostic 	 else  {
281bf48e50dSbostic 	      sprintf(lb,"T%d", p->vdim->dims[i].lbaddr->addrblock.memoffset->constblock.constant.ci);
2820fd3c7a0Sbostic          }
2830fd3c7a0Sbostic          if(p->vdim->dims[i].ubaddr == ENULL) {
284bf48e50dSbostic 	      sprintf(ub,"%d",p->vdim->dims[i].ub->constblock.constant.ci);
2850fd3c7a0Sbostic 	 }
2860fd3c7a0Sbostic 	 else  {
287bf48e50dSbostic 	      sprintf(ub,"T%d",p->vdim->dims[i].ubaddr->addrblock.memoffset->constblock.constant.ci);
2880fd3c7a0Sbostic          }
2890fd3c7a0Sbostic        	 sprintf(asmline+len, "ar%d;%s;%s;", TYINT, lb, ub);
2900fd3c7a0Sbostic 	 len += strlen(asmline+len);
2910fd3c7a0Sbostic      }
2920fd3c7a0Sbostic    }
2930fd3c7a0Sbostic     if (p->vtype == TYCHAR) {
2940fd3c7a0Sbostic     /* character type always an array(1:?) */
2950fd3c7a0Sbostic         if( ! (p->vleng ) )
2960fd3c7a0Sbostic            fatalstr("missing length in addtypeinfo for character variable %s", varstr(p->varname));
2970fd3c7a0Sbostic 
298bf48e50dSbostic         if (ISCONST(p->vleng)) sprintf(ub,"%d",p->vleng->constblock.constant.ci);
2990fd3c7a0Sbostic          else sprintf(ub,"A%d",p->vleng->addrblock.memno + ARGOFFSET);
3000fd3c7a0Sbostic 
3010fd3c7a0Sbostic 	sprintf(asmline+len,"ar%d;1;%s;", TYINT, ub);
3020fd3c7a0Sbostic 	len += strlen(asmline+len);
3030fd3c7a0Sbostic     }
3040fd3c7a0Sbostic     sprintf(asmline+len, "%d",tnum);
3050fd3c7a0Sbostic }
306