xref: /csrg-svn/usr.bin/f77/pass1.tahoe/stab.c (revision 46308)
143224Sbostic /*
243224Sbostic  * Copyright (c) 1980 Regents of the University of California.
343224Sbostic  * All rights reserved.  The Berkeley software License Agreement
443224Sbostic  * specifies the terms and conditions for redistribution.
543224Sbostic  */
643224Sbostic 
743224Sbostic #ifndef lint
843224Sbostic static char sccsid[] = "@(#)stab.c	5.1 (Berkeley) 6/7/85";
943224Sbostic #endif not lint
1043224Sbostic 
1143224Sbostic /*
1243224Sbostic  * stab.c
1343224Sbostic  *
1443224Sbostic  * Symbolic debugging info interface for the f77 compiler.
1543224Sbostic  *
1643224Sbostic  * Here we generate pseudo-ops that cause the assembler to put
1743224Sbostic  * symbolic debugging information into the object file.
1843224Sbostic  *
1943224Sbostic  * University of Utah CS Dept modification history:
2043224Sbostic  *
2143224Sbostic  * $Log:	stab.c,v $
2243224Sbostic  * Revision 1.2  85/02/02  01:30:09  donn
2343224Sbostic  * Don't put the 'program' name into the file; it only confuses dbx, sigh.
2443224Sbostic  *
2543224Sbostic  */
2643224Sbostic 
2743224Sbostic #include "defs.h"
2843224Sbostic 
2943224Sbostic #include <sys/types.h>
3043224Sbostic #include <a.out.h>
3143224Sbostic #include <stab.h>
3243224Sbostic 
3343224Sbostic #define public
3443224Sbostic #define private static
3543224Sbostic #define and &&
3643224Sbostic #define or ||
3743224Sbostic #define not !
3843224Sbostic #define div /
3943224Sbostic #define mod %
4043224Sbostic #define nil 0
4143224Sbostic 
4243224Sbostic typedef enum { false, true } Boolean;
4343224Sbostic 
4443224Sbostic static char asmline[128];
4543224Sbostic int len;
4643224Sbostic extern char *malloc();
4743224Sbostic 
4843224Sbostic prstab(s, code, type, loc)
4943224Sbostic char *s, *loc;
5043224Sbostic int code, type;
5143224Sbostic {
5243224Sbostic     char *locout;
5343224Sbostic 
5443224Sbostic     if (sdbflag) {
5543224Sbostic 	locout = (loc == nil) ? "0" : loc;
5643224Sbostic 	if (s == nil) {
5743224Sbostic 	    sprintf(asmline, "\t.stabn\t0x%x,0,0x%x,%s\n", code, type, locout);
5843224Sbostic 	} else {
5943224Sbostic 	    sprintf(asmline, "\t.stabs\t\"%s\",0x%x,0,0x%x,%s\n", s, code, type,
6043224Sbostic 		locout);
6143224Sbostic 	}
6243224Sbostic         p2pass( asmline );
6343224Sbostic     }
6443224Sbostic }
6543224Sbostic 
6643224Sbostic filenamestab(s)
6743224Sbostic char *s;
6843224Sbostic {
6943224Sbostic    sprintf(asmline,"\t.stabs\t\"%s\",0x%x,0,0,0\n", s, N_SO);
7043224Sbostic    p2pass( asmline );
7143224Sbostic }
7243224Sbostic 
7343224Sbostic linenostab(lineno)
7443224Sbostic int lineno;
7543224Sbostic {
7643224Sbostic    sprintf(asmline,"\t.stabd\t0x%x,0,%d\n", N_SLINE, lineno);
7743224Sbostic    p2pass( asmline );
7843224Sbostic }
7943224Sbostic 
8043224Sbostic /*
8143224Sbostic  * Generate information for an entry point
8243224Sbostic  */
8343224Sbostic 
8443224Sbostic public entrystab(p,class)
8543224Sbostic register struct Entrypoint *p;
8643224Sbostic int class;
8743224Sbostic {
8843224Sbostic int et;
8943224Sbostic Namep q;
9043224Sbostic 
9143224Sbostic   switch(class) {
9243224Sbostic     case CLMAIN:
9343224Sbostic         et=writestabtype(TYSUBR);
9443224Sbostic 	sprintf(asmline, "\t.stabs\t\"MAIN:F%2d\",0x%x,0,0,L%d\n",
9543224Sbostic 				et,N_FUN,p->entrylabel);
9643224Sbostic 	p2pass(asmline);
9743224Sbostic 	break;
9843224Sbostic 
9943224Sbostic      case CLBLOCK:     /* May need to something with block data LATER */
10043224Sbostic 	break;
10143224Sbostic 
10243224Sbostic      default :
10343224Sbostic  	if( (q=p->enamep) == nil) fatal("entrystab has no nameblock");
10443224Sbostic 	sprintf(asmline, "\t.stabs\t\"%s:F", varstr(VL,q->varname));
10543224Sbostic 	len = strlen(asmline);
10643224Sbostic 	/* when insufficient information is around assume TYSUBR; enddcl
10743224Sbostic 	   will fill this in*/
10843224Sbostic 	if(q->vtype == TYUNKNOWN || (q->vtype == TYCHAR && q->vleng == nil) ){
10943224Sbostic            sprintf(asmline+len, "%2d", writestabtype(TYSUBR));
11043224Sbostic  	}
11143224Sbostic         else addtypeinfo(q);
11243224Sbostic 	len += strlen(asmline+len);
11343224Sbostic 	sprintf(asmline+len, "\",0x%x,0,0,L%d\n",N_FUN,p->entrylabel);
11443224Sbostic 	p2pass(asmline);
11543224Sbostic         break;
11643224Sbostic    }
11743224Sbostic }
11843224Sbostic 
11943224Sbostic /*
12043224Sbostic  * Generate information for a symbol table (name block ) entry.
12143224Sbostic  */
12243224Sbostic 
12343224Sbostic public namestab(sym)
12443224Sbostic Namep sym;
12543224Sbostic {
12643224Sbostic     register Namep p;
12743224Sbostic     char *varname, *classname;
12843224Sbostic     Boolean ignore;
12943224Sbostic     int vartype;
13043224Sbostic 
13143224Sbostic 	ignore = false;
13243224Sbostic 	p = sym;
13343224Sbostic 	if(!p->vdcldone) return;
13443224Sbostic 	vartype = p->vtype;
13543224Sbostic 	varname = varstr(VL, p->varname);
13643224Sbostic 	switch (p->vclass) {
13743224Sbostic 	    case CLPARAM:	/* parameter (constant) */
13843224Sbostic 		classname = "c";
13943224Sbostic 		break;
14043224Sbostic 
14143224Sbostic 	    case CLVAR:		/* variable */
14243224Sbostic 	    case CLUNKNOWN:
14343224Sbostic  		if(p->vstg == STGARG) classname = "v";
14443224Sbostic     		else classname = "V";
14543224Sbostic 		break;
14643224Sbostic 
14743224Sbostic 	    case CLMAIN:	/* main program */
14843224Sbostic 	    case CLENTRY:	/* secondary entry point */
14943224Sbostic 	    case CLBLOCK:       /* block data name*/
15043224Sbostic 	    case CLPROC:	/* external or function or subroutine */
15143224Sbostic 		ignore = true;  /* these are put out by entrystab */
15243224Sbostic 		break;
15343224Sbostic 
15443224Sbostic 
15543224Sbostic 	}
15643224Sbostic 	if (not ignore) {
15743224Sbostic 	    sprintf(asmline, "\t.stabs\t\"%s:%s", varname, classname);
15843224Sbostic 	    len = strlen(asmline);
15943224Sbostic             addtypeinfo(p);
16043224Sbostic 	    len += strlen(asmline+len);
16143224Sbostic 	    switch(p->vstg) {
16243224Sbostic 
16343224Sbostic 	      case STGUNKNOWN :
16443224Sbostic 	      case STGCONST :
16543224Sbostic 	      case STGEXT :
16643224Sbostic 	      case STGINTR :
16743224Sbostic 	      case STGSTFUNCT :
16843224Sbostic 	      case STGLENG :
16943224Sbostic 	      case STGNULL :
17043224Sbostic 	      case STGREG :
17143224Sbostic 	      case STGINIT :
17243224Sbostic 	          sprintf(asmline+len,
17343224Sbostic 		  "\",0x%x,0,0,0 /* don't know how to calc loc for stg %d*/ \n",
17443224Sbostic 			       N_LSYM,p->vstg);
17543224Sbostic 		  break;
17643224Sbostic 
17743224Sbostic 	      case STGARG :
17843224Sbostic 		  sprintf(asmline+len,"\",0x%x,0,0,%d \n",
17943224Sbostic 			      N_PSYM,p->vardesc.varno + ARGOFFSET );
18043224Sbostic 		  break;
18143224Sbostic 
18243224Sbostic 	      case STGCOMMON :
18343224Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,%d\n",
18443224Sbostic 		       N_GSYM, p->voffset);
18543224Sbostic 		  break;
18643224Sbostic 
18743224Sbostic 	      case STGBSS :
18843224Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,v.%d\n",
18943224Sbostic 		     	 (p->inlcomm ? N_LCSYM : N_STSYM),
19043224Sbostic                          p->vardesc.varno);
19143224Sbostic 		  break;
19243224Sbostic 
19343224Sbostic 	      case STGEQUIV :
19443224Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,%s + %d \n",
19543224Sbostic 		     	 (p->inlcomm ? N_LCSYM : N_STSYM) ,
19643224Sbostic                          memname(STGEQUIV,p->vardesc.varno),(p->voffset)) ;
19743224Sbostic 		  break;
19843224Sbostic 
19943224Sbostic 	      case STGAUTO :
20043224Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,-%d \n",
20143224Sbostic 		     	N_LSYM, p->voffset);
20243224Sbostic 
20343224Sbostic 	    }
20443224Sbostic 	    p2pass(asmline);
20543224Sbostic 	}
20643224Sbostic }
20743224Sbostic 
20843224Sbostic static typenum[NTYPES]; /* has the given type already been defined ?*/
20943224Sbostic 
21043224Sbostic private writestabtype(type)
21143224Sbostic int type;
21243224Sbostic {
21343224Sbostic  char asmline[130];
21443224Sbostic  static char *typename[NTYPES] =
21543224Sbostic  { "unknown", "addr","integer*2", "integer", "real", "double precision",
21643224Sbostic    "complex", "double complex", "logical", "char", "void", "error" };
21743224Sbostic 
21843224Sbostic  static int typerange[NTYPES] = { 0, 3, 2, 3, 4, 5, 6, 7, 3, 9, 10, 11 };
21943224Sbostic 
22043224Sbostic  /* compare with typesize[] in init.c */
22143224Sbostic  static int typebounds[2] [NTYPES] ={
22243224Sbostic  /* "unknown", "addr","integer*2", "integer",    "real", "double precision", */
22343224Sbostic     { 0      ,   0   ,   -32768,    -2147483648,   4,       8,
22443224Sbostic  /* "complex", "double complex", "logical", "char", "void", "error" }; */
22543224Sbostic       8,         16,               0,        0,       0,          0 },
22643224Sbostic  /* "unknown", "addr","integer*2", "integer",    "real", "double precision", */
22743224Sbostic     { 0  ,       -1,      32767,    2147483647,   0,         0,
22843224Sbostic  /* "complex", "double complex", "logical", "char", "void", "error" }; */
22943224Sbostic       0,         0,               1,        127,       0,          0 }
23043224Sbostic  };
23143224Sbostic 
23243224Sbostic 
23343224Sbostic  if( type < 0 || type > NTYPES) badtype("writestabtype",type);
23443224Sbostic 
23543224Sbostic     if (typenum[type]) return(typenum[type]);
23643224Sbostic     typenum[type] = type;
23743224Sbostic     sprintf(asmline, "\t.stabs\t\"%s:t%d=r%d;%ld;%ld;\",0x%x,0,0,0 \n",
23843224Sbostic 	typename[type], type, typerange[type], typebounds[0][type],
23943224Sbostic         typebounds[1][type], N_GSYM) ;
24043224Sbostic     p2pass(asmline);
24143224Sbostic     return(typenum[type]);
24243224Sbostic }
24343224Sbostic 
24443224Sbostic 
24543224Sbostic private getbasenum(p)
24643224Sbostic Namep p;
24743224Sbostic {
24843224Sbostic 
24943224Sbostic   int t;
25043224Sbostic   t = p->vtype;
25143224Sbostic   if( t < TYSHORT || t > TYSUBR)
25243224Sbostic   dclerr("can't get dbx basetype information",p);
25343224Sbostic 
25443224Sbostic   if (p->vtype == TYCHAR || p->vdim != nil ) writestabtype(TYINT);
25543224Sbostic   return(writestabtype(t));
25643224Sbostic }
25743224Sbostic 
25843224Sbostic /*
25943224Sbostic  * Generate debugging information for the given type of the given symbol.
26043224Sbostic  */
26143224Sbostic 
26243224Sbostic private addtypeinfo(sym)
26343224Sbostic Namep sym;
26443224Sbostic {
26543224Sbostic     Namep p;
26643224Sbostic     int i,tnum;
26743224Sbostic     char lb[20],ub[20];
26843224Sbostic 
26943224Sbostic     p = sym;
27043224Sbostic     if (p->tag != TNAME) badtag("addtypeinfo",p->tag);
27143224Sbostic 
27243224Sbostic     tnum = getbasenum(p);
27343224Sbostic     if(p->vdim != (struct Dimblock *) ENULL) {
27443224Sbostic 
27543224Sbostic       for (i = p->vdim->ndim-1; i >=0 ; --i) {
27643224Sbostic          if(p->vdim->dims[i].lbaddr == ENULL) {
277*46308Sbostic 	      sprintf(lb,"%d", p->vdim->dims[i].lb->constblock.constant.ci);
27843224Sbostic 	 }
27943224Sbostic 	 else  {
280*46308Sbostic 	      sprintf(lb,"T%d", p->vdim->dims[i].lbaddr->addrblock.memoffset->constblock.constant.ci);
28143224Sbostic          }
28243224Sbostic          if(p->vdim->dims[i].ubaddr == ENULL) {
283*46308Sbostic 	      sprintf(ub,"%d",p->vdim->dims[i].ub->constblock.constant.ci);
28443224Sbostic 	 }
28543224Sbostic 	 else  {
286*46308Sbostic 	      sprintf(ub,"T%d",p->vdim->dims[i].ubaddr->addrblock.memoffset->constblock.constant.ci);
28743224Sbostic          }
28843224Sbostic        	 sprintf(asmline+len, "ar%d;%s;%s;", TYINT, lb, ub);
28943224Sbostic 	 len += strlen(asmline+len);
29043224Sbostic      }
29143224Sbostic    }
29243224Sbostic     if (p->vtype == TYCHAR) {
29343224Sbostic     /* character type always an array(1:?) */
29443224Sbostic         if( ! (p->vleng ) )
29543224Sbostic            fatalstr("missing length in addtypeinfo for character variable %s", varstr(p->varname));
29643224Sbostic 
297*46308Sbostic         if (ISCONST(p->vleng)) sprintf(ub,"%d",p->vleng->constblock.constant.ci);
29843224Sbostic          else sprintf(ub,"A%d",p->vleng->addrblock.memno + ARGOFFSET);
29943224Sbostic 
30043224Sbostic 	sprintf(asmline+len,"ar%d;1;%s;", TYINT, ub);
30143224Sbostic 	len += strlen(asmline+len);
30243224Sbostic     }
30343224Sbostic     sprintf(asmline+len, "%d",tnum);
30443224Sbostic }
305