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