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