xref: /csrg-svn/usr.bin/f77/pass1.vax/stab.c (revision 33257)
122872Smckusick /*
222872Smckusick  * Copyright (c) 1980 Regents of the University of California.
322872Smckusick  * All rights reserved.  The Berkeley software License Agreement
422872Smckusick  * specifies the terms and conditions for redistribution.
522872Smckusick  */
622872Smckusick 
722872Smckusick #ifndef lint
8*33257Sbostic static char sccsid[] = "@(#)stab.c	5.3 (Berkeley) 01/03/88";
922872Smckusick #endif not lint
1022872Smckusick 
1122872Smckusick /*
1222872Smckusick  * stab.c
1322872Smckusick  *
1422872Smckusick  * Symbolic debugging info interface for the f77 compiler.
1522872Smckusick  *
1622872Smckusick  * Here we generate pseudo-ops that cause the assembler to put
1722872Smckusick  * symbolic debugging information into the object file.
1822872Smckusick  *
1922872Smckusick  * University of Utah CS Dept modification history:
2022872Smckusick  *
2122872Smckusick  * $Log:	stab.c,v $
2225815Sdonn  * Revision 5.3  86/01/10  17:12:58  donn
2325815Sdonn  * Add junk to handle PARAMETER variables.
2425815Sdonn  *
2525815Sdonn  * Revision 5.2  86/01/10  13:51:31  donn
2625815Sdonn  * Changes to produce correct stab information for logical and logical*2 types
2725815Sdonn  * (from Jerry Berkman) plus changes for dummy procedures.
2825815Sdonn  *
2925815Sdonn  * Revision 5.1  85/08/10  03:50:06  donn
3025815Sdonn  * 4.3 alpha
3125815Sdonn  *
3222872Smckusick  * Revision 1.2  85/02/02  01:30:09  donn
3322872Smckusick  * Don't put the 'program' name into the file; it only confuses dbx, sigh.
3422872Smckusick  *
3522872Smckusick  */
3622872Smckusick 
3722872Smckusick #include "defs.h"
3822872Smckusick 
3922872Smckusick #include <sys/types.h>
4022872Smckusick #include <a.out.h>
4122872Smckusick #include <stab.h>
4222872Smckusick 
4322872Smckusick #define public
4422872Smckusick #define private static
4522872Smckusick #define and &&
4622872Smckusick #define or ||
4722872Smckusick #define not !
4822872Smckusick #define div /
4922872Smckusick #define mod %
5022872Smckusick #define nil 0
5122872Smckusick 
5222872Smckusick typedef enum { false, true } Boolean;
5322872Smckusick 
5422872Smckusick static char asmline[128];
5522872Smckusick int len;
5622872Smckusick extern char *malloc();
5722872Smckusick 
5822872Smckusick prstab(s, code, type, loc)
5922872Smckusick char *s, *loc;
6022872Smckusick int code, type;
6122872Smckusick {
6222872Smckusick     char *locout;
6322872Smckusick 
6422872Smckusick     if (sdbflag) {
6522872Smckusick 	locout = (loc == nil) ? "0" : loc;
6622872Smckusick 	if (s == nil) {
6722872Smckusick 	    sprintf(asmline, "\t.stabn\t0x%x,0,0x%x,%s\n", code, type, locout);
6822872Smckusick 	} else {
6922872Smckusick 	    sprintf(asmline, "\t.stabs\t\"%s\",0x%x,0,0x%x,%s\n", s, code, type,
7022872Smckusick 		locout);
7122872Smckusick 	}
7222872Smckusick         p2pass( asmline );
7322872Smckusick     }
7422872Smckusick }
7522872Smckusick 
7622872Smckusick filenamestab(s)
7722872Smckusick char *s;
7822872Smckusick {
7922872Smckusick    sprintf(asmline,"\t.stabs\t\"%s\",0x%x,0,0,0\n", s, N_SO);
8022872Smckusick    p2pass( asmline );
8122872Smckusick }
8222872Smckusick 
8322872Smckusick linenostab(lineno)
8422872Smckusick int lineno;
8522872Smckusick {
8622872Smckusick    sprintf(asmline,"\t.stabd\t0x%x,0,%d\n", N_SLINE, lineno);
8722872Smckusick    p2pass( asmline );
8822872Smckusick }
8922872Smckusick 
9022872Smckusick /*
9122872Smckusick  * Generate information for an entry point
9222872Smckusick  */
9322872Smckusick 
9422872Smckusick public entrystab(p,class)
9522872Smckusick register struct Entrypoint *p;
9622872Smckusick int class;
9722872Smckusick {
9822872Smckusick int et;
9922872Smckusick Namep q;
10022872Smckusick 
10122872Smckusick   switch(class) {
10222872Smckusick     case CLMAIN:
10322872Smckusick         et=writestabtype(TYSUBR);
10422872Smckusick 	sprintf(asmline, "\t.stabs\t\"MAIN:F%2d\",0x%x,0,0,L%d\n",
10522872Smckusick 				et,N_FUN,p->entrylabel);
10622872Smckusick 	p2pass(asmline);
10722872Smckusick 	break;
10822872Smckusick 
10922872Smckusick      case CLBLOCK:     /* May need to something with block data LATER */
11022872Smckusick 	break;
11122872Smckusick 
11222872Smckusick      default :
11322872Smckusick  	if( (q=p->enamep) == nil) fatal("entrystab has no nameblock");
11422872Smckusick 	sprintf(asmline, "\t.stabs\t\"%s:F", varstr(VL,q->varname));
11522872Smckusick 	len = strlen(asmline);
11622872Smckusick 	/* when insufficient information is around assume TYSUBR; enddcl
11722872Smckusick 	   will fill this in*/
11822872Smckusick 	if(q->vtype == TYUNKNOWN || (q->vtype == TYCHAR && q->vleng == nil) ){
11922872Smckusick            sprintf(asmline+len, "%2d", writestabtype(TYSUBR));
12022872Smckusick  	}
12122872Smckusick         else addtypeinfo(q);
12222872Smckusick 	len += strlen(asmline+len);
12322872Smckusick 	sprintf(asmline+len, "\",0x%x,0,0,L%d\n",N_FUN,p->entrylabel);
12422872Smckusick 	p2pass(asmline);
12522872Smckusick         break;
12622872Smckusick    }
12722872Smckusick }
12822872Smckusick 
12922872Smckusick /*
13022872Smckusick  * Generate information for a symbol table (name block ) entry.
13122872Smckusick  */
13222872Smckusick 
13322872Smckusick public namestab(sym)
13422872Smckusick Namep sym;
13522872Smckusick {
13622872Smckusick     register Namep p;
13722872Smckusick     char *varname, *classname;
13825815Sdonn     expptr ep;
13925815Sdonn     char buf[100];
14022872Smckusick     Boolean ignore;
14122872Smckusick     int vartype;
14222872Smckusick 
14322872Smckusick 	ignore = false;
14422872Smckusick 	p = sym;
14522872Smckusick 	if(!p->vdcldone) return;
14622872Smckusick 	vartype = p->vtype;
14722872Smckusick 	varname = varstr(VL, p->varname);
14822872Smckusick 	switch (p->vclass) {
14922872Smckusick 	    case CLPARAM:	/* parameter (constant) */
15025815Sdonn 		classname = buf;
15125815Sdonn 		if ((ep = ((struct Paramblock *) p)->paramval) &&
15225815Sdonn 		    ep->tag == TCONST) {
15325815Sdonn 		  switch(ep->constblock.vtype) {
15425815Sdonn 		    case TYLONG:
15525815Sdonn 		    case TYSHORT:
15625815Sdonn 		    case TYLOGICAL:
15725815Sdonn 		    case TYADDR:
158*33257Sbostic 		      sprintf(buf, "c=i%d", ep->constblock.constant.ci);
15925815Sdonn 		      break;
16025815Sdonn 		    case TYREAL:
16125815Sdonn 		    case TYDREAL:
162*33257Sbostic 		      sprintf(buf, "c=r%f", ep->constblock.constant.cd[0]);
16325815Sdonn 		      break;
16425815Sdonn 		    default:
16525815Sdonn 		      /* punt */
16625815Sdonn 		      ignore = true;
16725815Sdonn 		      break;
16825815Sdonn 		  }
16925815Sdonn 		} else {
17025815Sdonn 		  ignore = true;
17125815Sdonn 		}
17222872Smckusick 		break;
17322872Smckusick 
17422872Smckusick 	    case CLVAR:		/* variable */
17522872Smckusick 	    case CLUNKNOWN:
17622872Smckusick  		if(p->vstg == STGARG) classname = "v";
17722872Smckusick     		else classname = "V";
17822872Smckusick 		break;
17922872Smckusick 
18025815Sdonn 	    case CLPROC:	/* external or function or subroutine */
18125815Sdonn 		if(p->vstg == STGARG) {
18225815Sdonn 		    classname = "v";
18325815Sdonn 		    break;
18425815Sdonn 		}
18525815Sdonn 		/* FALL THROUGH */
18622872Smckusick 	    case CLMAIN:	/* main program */
18722872Smckusick 	    case CLENTRY:	/* secondary entry point */
18822872Smckusick 	    case CLBLOCK:       /* block data name*/
18922872Smckusick 		ignore = true;  /* these are put out by entrystab */
19022872Smckusick 		break;
19122872Smckusick 
19222872Smckusick 
19322872Smckusick 	}
19422872Smckusick 	if (not ignore) {
19522872Smckusick 	    sprintf(asmline, "\t.stabs\t\"%s:%s", varname, classname);
19622872Smckusick 	    len = strlen(asmline);
19722872Smckusick             addtypeinfo(p);
19822872Smckusick 	    len += strlen(asmline+len);
19922872Smckusick 	    switch(p->vstg) {
20022872Smckusick 
20122872Smckusick 	      case STGUNKNOWN :
20222872Smckusick 	      case STGCONST :
20322872Smckusick 	      case STGEXT :
20422872Smckusick 	      case STGINTR :
20522872Smckusick 	      case STGSTFUNCT :
20622872Smckusick 	      case STGLENG :
20722872Smckusick 	      case STGNULL :
20822872Smckusick 	      case STGREG :
20922872Smckusick 	      case STGINIT :
21025815Sdonn 		  if (p->vclass == CLPARAM) {
21125815Sdonn 		      /* these have zero storage class for some reason */
21225815Sdonn 		      sprintf(asmline+len, "\",0x%x,0,0,0\n", N_LSYM);
21325815Sdonn 		      break;
21425815Sdonn 		  }
21522872Smckusick 	          sprintf(asmline+len,
21622872Smckusick 		  "\",0x%x,0,0,0 /* don't know how to calc loc for stg %d*/ \n",
21722872Smckusick 			       N_LSYM,p->vstg);
21822872Smckusick 		  break;
21922872Smckusick 
22022872Smckusick 	      case STGARG :
22122872Smckusick 		  sprintf(asmline+len,"\",0x%x,0,0,%d \n",
22222872Smckusick 			      N_PSYM,p->vardesc.varno + ARGOFFSET );
22322872Smckusick 		  break;
22422872Smckusick 
22522872Smckusick 	      case STGCOMMON :
22622872Smckusick 		  sprintf(asmline+len, "\",0x%x,0,0,%d\n",
22722872Smckusick 		       N_GSYM, p->voffset);
22822872Smckusick 		  break;
22922872Smckusick 
23022872Smckusick 	      case STGBSS :
23122872Smckusick 		  sprintf(asmline+len, "\",0x%x,0,0,v.%d\n",
23222872Smckusick 		     	 (p->inlcomm ? N_LCSYM : N_STSYM),
23322872Smckusick                          p->vardesc.varno);
23422872Smckusick 		  break;
23522872Smckusick 
23622872Smckusick 	      case STGEQUIV :
23722872Smckusick 		  sprintf(asmline+len, "\",0x%x,0,0,%s + %d \n",
23822872Smckusick 		     	 (p->inlcomm ? N_LCSYM : N_STSYM) ,
23922872Smckusick                          memname(STGEQUIV,p->vardesc.varno),(p->voffset)) ;
24022872Smckusick 		  break;
24122872Smckusick 
24222872Smckusick 	      case STGAUTO :
24322872Smckusick 		  sprintf(asmline+len, "\",0x%x,0,0,-%d \n",
24422872Smckusick 		     	N_LSYM, p->voffset);
24522872Smckusick 
24622872Smckusick 	    }
24722872Smckusick 	    p2pass(asmline);
24822872Smckusick 	}
24922872Smckusick }
25022872Smckusick 
25125815Sdonn static typenum[NTYPES+1]; /* has the given type already been defined ?*/
25222872Smckusick 
25322872Smckusick private writestabtype(type)
25422872Smckusick int type;
25522872Smckusick {
25622872Smckusick  char asmline[130];
25725815Sdonn  static char *typename[NTYPES+1] = {
25825815Sdonn  "unknown", "addr", "integer*2", "integer", "real", "double precision",
25925815Sdonn  "complex", "double complex", "logical", "char", "void", "error", "logical*2" };
26022872Smckusick 
26125815Sdonn  static int typerange[NTYPES+1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
26222872Smckusick 
26322872Smckusick  /* compare with typesize[] in init.c */
26425815Sdonn  static int typebounds[2] [NTYPES+1] ={
26522872Smckusick  /* "unknown", "addr","integer*2", "integer",    "real", "double precision", */
26622872Smckusick     { 0      ,   0   ,   -32768,    -2147483648,   4,       8,
26725815Sdonn  /* "complex", "d-complex", "logical", "char", "void", "error", "logical*2" */
26825815Sdonn       8,         16,          4,        0,       0,      0,       2 },
26922872Smckusick  /* "unknown", "addr","integer*2", "integer",    "real", "double precision", */
27025815Sdonn     { 0  ,       -1,      32767,    2147483647,    0,       0,
27125815Sdonn  /* "complex", "d-complex", "logical", "char", "void", "error", "logical*2" */
27225815Sdonn       0,         0,           0,        127,     0,      0,       0 }
27322872Smckusick  };
27422872Smckusick 
27522872Smckusick 
27625815Sdonn     if (type < 0 || type > NTYPES)
27725815Sdonn 	badtype("writestabtype",type);
27822872Smckusick 
27925815Sdonn     /* substitute "logical*2" for "logical" when "-i2" compiler flag used */
28025815Sdonn     if (type == TYLOGICAL && tylogical == TYSHORT)
28125815Sdonn 	type = NTYPES;
28225815Sdonn 
28322872Smckusick     if (typenum[type]) return(typenum[type]);
28422872Smckusick     typenum[type] = type;
28522872Smckusick     sprintf(asmline, "\t.stabs\t\"%s:t%d=r%d;%ld;%ld;\",0x%x,0,0,0 \n",
28622872Smckusick 	typename[type], type, typerange[type], typebounds[0][type],
28722872Smckusick         typebounds[1][type], N_GSYM) ;
28822872Smckusick     p2pass(asmline);
28922872Smckusick     return(typenum[type]);
29022872Smckusick }
29122872Smckusick 
29222872Smckusick 
29322872Smckusick private getbasenum(p)
29422872Smckusick Namep p;
29522872Smckusick {
29622872Smckusick 
29722872Smckusick   int t;
29822872Smckusick 
29925815Sdonn   if (p->vclass == CLPROC && p->vstg == STGARG)
30025815Sdonn     t = TYADDR;
30125815Sdonn   else
30225815Sdonn     t = p->vtype;
30325815Sdonn 
30425815Sdonn   if (t < TYADDR || t > TYSUBR)
30525815Sdonn     dclerr("can't get dbx basetype information",p);
30625815Sdonn 
30725815Sdonn   if (p->vtype == TYCHAR || p->vdim != nil)
30825815Sdonn     writestabtype(TYINT);
30922872Smckusick   return(writestabtype(t));
31022872Smckusick }
31122872Smckusick 
31222872Smckusick /*
31322872Smckusick  * Generate debugging information for the given type of the given symbol.
31422872Smckusick  */
31522872Smckusick 
31622872Smckusick private addtypeinfo(sym)
31722872Smckusick Namep sym;
31822872Smckusick {
31922872Smckusick     Namep p;
32022872Smckusick     int i,tnum;
32122872Smckusick     char lb[20],ub[20];
32222872Smckusick 
32322872Smckusick     p = sym;
32422872Smckusick     if (p->tag != TNAME) badtag("addtypeinfo",p->tag);
32525815Sdonn     if (p->vclass == CLPARAM)
32625815Sdonn 	return;
32722872Smckusick 
32822872Smckusick     tnum = getbasenum(p);
32922872Smckusick     if(p->vdim != (struct Dimblock *) ENULL) {
33022872Smckusick 
33122872Smckusick       for (i = p->vdim->ndim-1; i >=0 ; --i) {
33222872Smckusick          if(p->vdim->dims[i].lbaddr == ENULL) {
333*33257Sbostic 	      sprintf(lb,"%d", p->vdim->dims[i].lb->constblock.constant.ci);
33422872Smckusick 	 }
33522872Smckusick 	 else  {
336*33257Sbostic 	      sprintf(lb,"T%d", p->vdim->dims[i].lbaddr->addrblock.memoffset->constblock.constant.ci);
33722872Smckusick          }
33822872Smckusick          if(p->vdim->dims[i].ubaddr == ENULL) {
339*33257Sbostic 	      sprintf(ub,"%d",p->vdim->dims[i].ub->constblock.constant.ci);
34022872Smckusick 	 }
34122872Smckusick 	 else  {
342*33257Sbostic 	      sprintf(ub,"T%d",p->vdim->dims[i].ubaddr->addrblock.memoffset->constblock.constant.ci);
34322872Smckusick          }
34422872Smckusick        	 sprintf(asmline+len, "ar%d;%s;%s;", TYINT, lb, ub);
34522872Smckusick 	 len += strlen(asmline+len);
34622872Smckusick      }
34722872Smckusick    }
34822872Smckusick     if (p->vtype == TYCHAR) {
34922872Smckusick     /* character type always an array(1:?) */
35022872Smckusick         if( ! (p->vleng ) )
35122872Smckusick            fatalstr("missing length in addtypeinfo for character variable %s", varstr(p->varname));
35222872Smckusick 
353*33257Sbostic         if (ISCONST(p->vleng)) sprintf(ub,"%d",p->vleng->constblock.constant.ci);
35422872Smckusick          else sprintf(ub,"A%d",p->vleng->addrblock.memno + ARGOFFSET);
35522872Smckusick 
35622872Smckusick 	sprintf(asmline+len,"ar%d;1;%s;", TYINT, ub);
35722872Smckusick 	len += strlen(asmline+len);
35822872Smckusick     }
35922872Smckusick     sprintf(asmline+len, "%d",tnum);
36022872Smckusick }
361