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