xref: /csrg-svn/usr.bin/f77/pass1.tahoe/stab.c (revision 43224)
1*43224Sbostic /*
2*43224Sbostic  * Copyright (c) 1980 Regents of the University of California.
3*43224Sbostic  * All rights reserved.  The Berkeley software License Agreement
4*43224Sbostic  * specifies the terms and conditions for redistribution.
5*43224Sbostic  */
6*43224Sbostic 
7*43224Sbostic #ifndef lint
8*43224Sbostic static char sccsid[] = "@(#)stab.c	5.1 (Berkeley) 6/7/85";
9*43224Sbostic #endif not lint
10*43224Sbostic 
11*43224Sbostic /*
12*43224Sbostic  * stab.c
13*43224Sbostic  *
14*43224Sbostic  * Symbolic debugging info interface for the f77 compiler.
15*43224Sbostic  *
16*43224Sbostic  * Here we generate pseudo-ops that cause the assembler to put
17*43224Sbostic  * symbolic debugging information into the object file.
18*43224Sbostic  *
19*43224Sbostic  * University of Utah CS Dept modification history:
20*43224Sbostic  *
21*43224Sbostic  * $Log:	stab.c,v $
22*43224Sbostic  * Revision 1.2  85/02/02  01:30:09  donn
23*43224Sbostic  * Don't put the 'program' name into the file; it only confuses dbx, sigh.
24*43224Sbostic  *
25*43224Sbostic  */
26*43224Sbostic 
27*43224Sbostic #include "defs.h"
28*43224Sbostic 
29*43224Sbostic #include <sys/types.h>
30*43224Sbostic #include <a.out.h>
31*43224Sbostic #include <stab.h>
32*43224Sbostic 
33*43224Sbostic #define public
34*43224Sbostic #define private static
35*43224Sbostic #define and &&
36*43224Sbostic #define or ||
37*43224Sbostic #define not !
38*43224Sbostic #define div /
39*43224Sbostic #define mod %
40*43224Sbostic #define nil 0
41*43224Sbostic 
42*43224Sbostic typedef enum { false, true } Boolean;
43*43224Sbostic 
44*43224Sbostic static char asmline[128];
45*43224Sbostic int len;
46*43224Sbostic extern char *malloc();
47*43224Sbostic 
48*43224Sbostic prstab(s, code, type, loc)
49*43224Sbostic char *s, *loc;
50*43224Sbostic int code, type;
51*43224Sbostic {
52*43224Sbostic     char *locout;
53*43224Sbostic 
54*43224Sbostic     if (sdbflag) {
55*43224Sbostic 	locout = (loc == nil) ? "0" : loc;
56*43224Sbostic 	if (s == nil) {
57*43224Sbostic 	    sprintf(asmline, "\t.stabn\t0x%x,0,0x%x,%s\n", code, type, locout);
58*43224Sbostic 	} else {
59*43224Sbostic 	    sprintf(asmline, "\t.stabs\t\"%s\",0x%x,0,0x%x,%s\n", s, code, type,
60*43224Sbostic 		locout);
61*43224Sbostic 	}
62*43224Sbostic         p2pass( asmline );
63*43224Sbostic     }
64*43224Sbostic }
65*43224Sbostic 
66*43224Sbostic filenamestab(s)
67*43224Sbostic char *s;
68*43224Sbostic {
69*43224Sbostic    sprintf(asmline,"\t.stabs\t\"%s\",0x%x,0,0,0\n", s, N_SO);
70*43224Sbostic    p2pass( asmline );
71*43224Sbostic }
72*43224Sbostic 
73*43224Sbostic linenostab(lineno)
74*43224Sbostic int lineno;
75*43224Sbostic {
76*43224Sbostic    sprintf(asmline,"\t.stabd\t0x%x,0,%d\n", N_SLINE, lineno);
77*43224Sbostic    p2pass( asmline );
78*43224Sbostic }
79*43224Sbostic 
80*43224Sbostic /*
81*43224Sbostic  * Generate information for an entry point
82*43224Sbostic  */
83*43224Sbostic 
84*43224Sbostic public entrystab(p,class)
85*43224Sbostic register struct Entrypoint *p;
86*43224Sbostic int class;
87*43224Sbostic {
88*43224Sbostic int et;
89*43224Sbostic Namep q;
90*43224Sbostic 
91*43224Sbostic   switch(class) {
92*43224Sbostic     case CLMAIN:
93*43224Sbostic         et=writestabtype(TYSUBR);
94*43224Sbostic 	sprintf(asmline, "\t.stabs\t\"MAIN:F%2d\",0x%x,0,0,L%d\n",
95*43224Sbostic 				et,N_FUN,p->entrylabel);
96*43224Sbostic 	p2pass(asmline);
97*43224Sbostic 	break;
98*43224Sbostic 
99*43224Sbostic      case CLBLOCK:     /* May need to something with block data LATER */
100*43224Sbostic 	break;
101*43224Sbostic 
102*43224Sbostic      default :
103*43224Sbostic  	if( (q=p->enamep) == nil) fatal("entrystab has no nameblock");
104*43224Sbostic 	sprintf(asmline, "\t.stabs\t\"%s:F", varstr(VL,q->varname));
105*43224Sbostic 	len = strlen(asmline);
106*43224Sbostic 	/* when insufficient information is around assume TYSUBR; enddcl
107*43224Sbostic 	   will fill this in*/
108*43224Sbostic 	if(q->vtype == TYUNKNOWN || (q->vtype == TYCHAR && q->vleng == nil) ){
109*43224Sbostic            sprintf(asmline+len, "%2d", writestabtype(TYSUBR));
110*43224Sbostic  	}
111*43224Sbostic         else addtypeinfo(q);
112*43224Sbostic 	len += strlen(asmline+len);
113*43224Sbostic 	sprintf(asmline+len, "\",0x%x,0,0,L%d\n",N_FUN,p->entrylabel);
114*43224Sbostic 	p2pass(asmline);
115*43224Sbostic         break;
116*43224Sbostic    }
117*43224Sbostic }
118*43224Sbostic 
119*43224Sbostic /*
120*43224Sbostic  * Generate information for a symbol table (name block ) entry.
121*43224Sbostic  */
122*43224Sbostic 
123*43224Sbostic public namestab(sym)
124*43224Sbostic Namep sym;
125*43224Sbostic {
126*43224Sbostic     register Namep p;
127*43224Sbostic     char *varname, *classname;
128*43224Sbostic     Boolean ignore;
129*43224Sbostic     int vartype;
130*43224Sbostic 
131*43224Sbostic 	ignore = false;
132*43224Sbostic 	p = sym;
133*43224Sbostic 	if(!p->vdcldone) return;
134*43224Sbostic 	vartype = p->vtype;
135*43224Sbostic 	varname = varstr(VL, p->varname);
136*43224Sbostic 	switch (p->vclass) {
137*43224Sbostic 	    case CLPARAM:	/* parameter (constant) */
138*43224Sbostic 		classname = "c";
139*43224Sbostic 		break;
140*43224Sbostic 
141*43224Sbostic 	    case CLVAR:		/* variable */
142*43224Sbostic 	    case CLUNKNOWN:
143*43224Sbostic  		if(p->vstg == STGARG) classname = "v";
144*43224Sbostic     		else classname = "V";
145*43224Sbostic 		break;
146*43224Sbostic 
147*43224Sbostic 	    case CLMAIN:	/* main program */
148*43224Sbostic 	    case CLENTRY:	/* secondary entry point */
149*43224Sbostic 	    case CLBLOCK:       /* block data name*/
150*43224Sbostic 	    case CLPROC:	/* external or function or subroutine */
151*43224Sbostic 		ignore = true;  /* these are put out by entrystab */
152*43224Sbostic 		break;
153*43224Sbostic 
154*43224Sbostic 
155*43224Sbostic 	}
156*43224Sbostic 	if (not ignore) {
157*43224Sbostic 	    sprintf(asmline, "\t.stabs\t\"%s:%s", varname, classname);
158*43224Sbostic 	    len = strlen(asmline);
159*43224Sbostic             addtypeinfo(p);
160*43224Sbostic 	    len += strlen(asmline+len);
161*43224Sbostic 	    switch(p->vstg) {
162*43224Sbostic 
163*43224Sbostic 	      case STGUNKNOWN :
164*43224Sbostic 	      case STGCONST :
165*43224Sbostic 	      case STGEXT :
166*43224Sbostic 	      case STGINTR :
167*43224Sbostic 	      case STGSTFUNCT :
168*43224Sbostic 	      case STGLENG :
169*43224Sbostic 	      case STGNULL :
170*43224Sbostic 	      case STGREG :
171*43224Sbostic 	      case STGINIT :
172*43224Sbostic 	          sprintf(asmline+len,
173*43224Sbostic 		  "\",0x%x,0,0,0 /* don't know how to calc loc for stg %d*/ \n",
174*43224Sbostic 			       N_LSYM,p->vstg);
175*43224Sbostic 		  break;
176*43224Sbostic 
177*43224Sbostic 	      case STGARG :
178*43224Sbostic 		  sprintf(asmline+len,"\",0x%x,0,0,%d \n",
179*43224Sbostic 			      N_PSYM,p->vardesc.varno + ARGOFFSET );
180*43224Sbostic 		  break;
181*43224Sbostic 
182*43224Sbostic 	      case STGCOMMON :
183*43224Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,%d\n",
184*43224Sbostic 		       N_GSYM, p->voffset);
185*43224Sbostic 		  break;
186*43224Sbostic 
187*43224Sbostic 	      case STGBSS :
188*43224Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,v.%d\n",
189*43224Sbostic 		     	 (p->inlcomm ? N_LCSYM : N_STSYM),
190*43224Sbostic                          p->vardesc.varno);
191*43224Sbostic 		  break;
192*43224Sbostic 
193*43224Sbostic 	      case STGEQUIV :
194*43224Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,%s + %d \n",
195*43224Sbostic 		     	 (p->inlcomm ? N_LCSYM : N_STSYM) ,
196*43224Sbostic                          memname(STGEQUIV,p->vardesc.varno),(p->voffset)) ;
197*43224Sbostic 		  break;
198*43224Sbostic 
199*43224Sbostic 	      case STGAUTO :
200*43224Sbostic 		  sprintf(asmline+len, "\",0x%x,0,0,-%d \n",
201*43224Sbostic 		     	N_LSYM, p->voffset);
202*43224Sbostic 
203*43224Sbostic 	    }
204*43224Sbostic 	    p2pass(asmline);
205*43224Sbostic 	}
206*43224Sbostic }
207*43224Sbostic 
208*43224Sbostic static typenum[NTYPES]; /* has the given type already been defined ?*/
209*43224Sbostic 
210*43224Sbostic private writestabtype(type)
211*43224Sbostic int type;
212*43224Sbostic {
213*43224Sbostic  char asmline[130];
214*43224Sbostic  static char *typename[NTYPES] =
215*43224Sbostic  { "unknown", "addr","integer*2", "integer", "real", "double precision",
216*43224Sbostic    "complex", "double complex", "logical", "char", "void", "error" };
217*43224Sbostic 
218*43224Sbostic  static int typerange[NTYPES] = { 0, 3, 2, 3, 4, 5, 6, 7, 3, 9, 10, 11 };
219*43224Sbostic 
220*43224Sbostic  /* compare with typesize[] in init.c */
221*43224Sbostic  static int typebounds[2] [NTYPES] ={
222*43224Sbostic  /* "unknown", "addr","integer*2", "integer",    "real", "double precision", */
223*43224Sbostic     { 0      ,   0   ,   -32768,    -2147483648,   4,       8,
224*43224Sbostic  /* "complex", "double complex", "logical", "char", "void", "error" }; */
225*43224Sbostic       8,         16,               0,        0,       0,          0 },
226*43224Sbostic  /* "unknown", "addr","integer*2", "integer",    "real", "double precision", */
227*43224Sbostic     { 0  ,       -1,      32767,    2147483647,   0,         0,
228*43224Sbostic  /* "complex", "double complex", "logical", "char", "void", "error" }; */
229*43224Sbostic       0,         0,               1,        127,       0,          0 }
230*43224Sbostic  };
231*43224Sbostic 
232*43224Sbostic 
233*43224Sbostic  if( type < 0 || type > NTYPES) badtype("writestabtype",type);
234*43224Sbostic 
235*43224Sbostic     if (typenum[type]) return(typenum[type]);
236*43224Sbostic     typenum[type] = type;
237*43224Sbostic     sprintf(asmline, "\t.stabs\t\"%s:t%d=r%d;%ld;%ld;\",0x%x,0,0,0 \n",
238*43224Sbostic 	typename[type], type, typerange[type], typebounds[0][type],
239*43224Sbostic         typebounds[1][type], N_GSYM) ;
240*43224Sbostic     p2pass(asmline);
241*43224Sbostic     return(typenum[type]);
242*43224Sbostic }
243*43224Sbostic 
244*43224Sbostic 
245*43224Sbostic private getbasenum(p)
246*43224Sbostic Namep p;
247*43224Sbostic {
248*43224Sbostic 
249*43224Sbostic   int t;
250*43224Sbostic   t = p->vtype;
251*43224Sbostic   if( t < TYSHORT || t > TYSUBR)
252*43224Sbostic   dclerr("can't get dbx basetype information",p);
253*43224Sbostic 
254*43224Sbostic   if (p->vtype == TYCHAR || p->vdim != nil ) writestabtype(TYINT);
255*43224Sbostic   return(writestabtype(t));
256*43224Sbostic }
257*43224Sbostic 
258*43224Sbostic /*
259*43224Sbostic  * Generate debugging information for the given type of the given symbol.
260*43224Sbostic  */
261*43224Sbostic 
262*43224Sbostic private addtypeinfo(sym)
263*43224Sbostic Namep sym;
264*43224Sbostic {
265*43224Sbostic     Namep p;
266*43224Sbostic     int i,tnum;
267*43224Sbostic     char lb[20],ub[20];
268*43224Sbostic 
269*43224Sbostic     p = sym;
270*43224Sbostic     if (p->tag != TNAME) badtag("addtypeinfo",p->tag);
271*43224Sbostic 
272*43224Sbostic     tnum = getbasenum(p);
273*43224Sbostic     if(p->vdim != (struct Dimblock *) ENULL) {
274*43224Sbostic 
275*43224Sbostic       for (i = p->vdim->ndim-1; i >=0 ; --i) {
276*43224Sbostic          if(p->vdim->dims[i].lbaddr == ENULL) {
277*43224Sbostic 	      sprintf(lb,"%d", p->vdim->dims[i].lb->constblock.const.ci);
278*43224Sbostic 	 }
279*43224Sbostic 	 else  {
280*43224Sbostic 	      sprintf(lb,"T%d", p->vdim->dims[i].lbaddr->addrblock.memoffset->constblock.const.ci);
281*43224Sbostic          }
282*43224Sbostic          if(p->vdim->dims[i].ubaddr == ENULL) {
283*43224Sbostic 	      sprintf(ub,"%d",p->vdim->dims[i].ub->constblock.const.ci);
284*43224Sbostic 	 }
285*43224Sbostic 	 else  {
286*43224Sbostic 	      sprintf(ub,"T%d",p->vdim->dims[i].ubaddr->addrblock.memoffset->constblock.const.ci);
287*43224Sbostic          }
288*43224Sbostic        	 sprintf(asmline+len, "ar%d;%s;%s;", TYINT, lb, ub);
289*43224Sbostic 	 len += strlen(asmline+len);
290*43224Sbostic      }
291*43224Sbostic    }
292*43224Sbostic     if (p->vtype == TYCHAR) {
293*43224Sbostic     /* character type always an array(1:?) */
294*43224Sbostic         if( ! (p->vleng ) )
295*43224Sbostic            fatalstr("missing length in addtypeinfo for character variable %s", varstr(p->varname));
296*43224Sbostic 
297*43224Sbostic         if (ISCONST(p->vleng)) sprintf(ub,"%d",p->vleng->constblock.const.ci);
298*43224Sbostic          else sprintf(ub,"A%d",p->vleng->addrblock.memno + ARGOFFSET);
299*43224Sbostic 
300*43224Sbostic 	sprintf(asmline+len,"ar%d;1;%s;", TYINT, ub);
301*43224Sbostic 	len += strlen(asmline+len);
302*43224Sbostic     }
303*43224Sbostic     sprintf(asmline+len, "%d",tnum);
304*43224Sbostic }
305