date and time created 90/06/17 18:09:03 by bostic
[unix-history] / usr / src / usr.bin / f77 / pass1.tahoe / stab.c
CommitLineData
1364805a
KB
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
8static 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
42typedef enum { false, true } Boolean;
43
44static char asmline[128];
45int len;
46extern char *malloc();
47
48prstab(s, code, type, loc)
49char *s, *loc;
50int 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
66filenamestab(s)
67char *s;
68{
69 sprintf(asmline,"\t.stabs\t\"%s\",0x%x,0,0,0\n", s, N_SO);
70 p2pass( asmline );
71}
72
73linenostab(lineno)
74int 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
84public entrystab(p,class)
85register struct Entrypoint *p;
86int class;
87{
88int et;
89Namep 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
123public namestab(sym)
124Namep 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
208static typenum[NTYPES]; /* has the given type already been defined ?*/
209
210private writestabtype(type)
211int 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
245private getbasenum(p)
246Namep 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
262private addtypeinfo(sym)
263Namep 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}