BSD 4_3_Tahoe release
[unix-history] / usr / src / usr.bin / f77 / f77.vax / f77pass1 / stab.c
CommitLineData
3be3d0a4
KM
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
ca67e7b4 8static char sccsid[] = "@(#)stab.c 5.3 (Berkeley) 1/3/88";
3be3d0a4
KM
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 $
6f672207
DS
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 *
3be3d0a4
KM
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
52typedef enum { false, true } Boolean;
53
54static char asmline[128];
55int len;
56extern char *malloc();
57
58prstab(s, code, type, loc)
59char *s, *loc;
60int 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
76filenamestab(s)
77char *s;
78{
79 sprintf(asmline,"\t.stabs\t\"%s\",0x%x,0,0,0\n", s, N_SO);
80 p2pass( asmline );
81}
82
83linenostab(lineno)
84int 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
94public entrystab(p,class)
95register struct Entrypoint *p;
96int class;
97{
98int et;
99Namep 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
133public namestab(sym)
134Namep sym;
135{
136 register Namep p;
137 char *varname, *classname;
6f672207
DS
138 expptr ep;
139 char buf[100];
3be3d0a4
KM
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) */
6f672207
DS
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:
9868d2fe 158 sprintf(buf, "c=i%d", ep->constblock.constant.ci);
6f672207
DS
159 break;
160 case TYREAL:
161 case TYDREAL:
9868d2fe 162 sprintf(buf, "c=r%f", ep->constblock.constant.cd[0]);
6f672207
DS
163 break;
164 default:
165 /* punt */
166 ignore = true;
167 break;
168 }
169 } else {
170 ignore = true;
171 }
3be3d0a4
KM
172 break;
173
174 case CLVAR: /* variable */
175 case CLUNKNOWN:
176 if(p->vstg == STGARG) classname = "v";
177 else classname = "V";
178 break;
179
6f672207
DS
180 case CLPROC: /* external or function or subroutine */
181 if(p->vstg == STGARG) {
182 classname = "v";
183 break;
184 }
185 /* FALL THROUGH */
3be3d0a4
KM
186 case CLMAIN: /* main program */
187 case CLENTRY: /* secondary entry point */
188 case CLBLOCK: /* block data name*/
3be3d0a4
KM
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 :
6f672207
DS
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 }
3be3d0a4
KM
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
6f672207 251static typenum[NTYPES+1]; /* has the given type already been defined ?*/
3be3d0a4
KM
252
253private writestabtype(type)
254int type;
255{
256 char asmline[130];
6f672207
DS
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" };
3be3d0a4 260
6f672207 261 static int typerange[NTYPES+1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
3be3d0a4
KM
262
263 /* compare with typesize[] in init.c */
6f672207 264 static int typebounds[2] [NTYPES+1] ={
3be3d0a4
KM
265 /* "unknown", "addr","integer*2", "integer", "real", "double precision", */
266 { 0 , 0 , -32768, -2147483648, 4, 8,
6f672207
DS
267 /* "complex", "d-complex", "logical", "char", "void", "error", "logical*2" */
268 8, 16, 4, 0, 0, 0, 2 },
3be3d0a4 269 /* "unknown", "addr","integer*2", "integer", "real", "double precision", */
6f672207
DS
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 }
3be3d0a4
KM
273 };
274
275
6f672207
DS
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;
3be3d0a4
KM
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
293private getbasenum(p)
294Namep p;
295{
296
297 int t;
3be3d0a4 298
6f672207
DS
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);
3be3d0a4
KM
309 return(writestabtype(t));
310}
311
312/*
313 * Generate debugging information for the given type of the given symbol.
314 */
315
316private addtypeinfo(sym)
317Namep 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);
6f672207
DS
325 if (p->vclass == CLPARAM)
326 return;
3be3d0a4
KM
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) {
9868d2fe 333 sprintf(lb,"%d", p->vdim->dims[i].lb->constblock.constant.ci);
3be3d0a4
KM
334 }
335 else {
9868d2fe 336 sprintf(lb,"T%d", p->vdim->dims[i].lbaddr->addrblock.memoffset->constblock.constant.ci);
3be3d0a4
KM
337 }
338 if(p->vdim->dims[i].ubaddr == ENULL) {
9868d2fe 339 sprintf(ub,"%d",p->vdim->dims[i].ub->constblock.constant.ci);
3be3d0a4
KM
340 }
341 else {
9868d2fe 342 sprintf(ub,"T%d",p->vdim->dims[i].ubaddr->addrblock.memoffset->constblock.constant.ci);
3be3d0a4
KM
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
9868d2fe 353 if (ISCONST(p->vleng)) sprintf(ub,"%d",p->vleng->constblock.constant.ci);
3be3d0a4
KM
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}