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