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
prstab(s,code,type,loc)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
filenamestab(s)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
linenostab(lineno)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
entrystab(p,class)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
namestab(sym)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
writestabtype(type)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
getbasenum(p)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
addtypeinfo(sym)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