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