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