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