1*47951Sbostic /*-
2*47951Sbostic * Copyright (c) 1980 The Regents of the University of California.
3*47951Sbostic * All rights reserved.
4*47951Sbostic *
5*47951Sbostic * %sccs.include.proprietary.c%
643224Sbostic */
743224Sbostic
843224Sbostic #ifndef lint
9*47951Sbostic static char sccsid[] = "@(#)stab.c 5.3 (Berkeley) 04/12/91";
10*47951Sbostic #endif /* not lint */
1143224Sbostic
1243224Sbostic /*
1343224Sbostic * stab.c
1443224Sbostic *
1543224Sbostic * Symbolic debugging info interface for the f77 compiler.
1643224Sbostic *
1743224Sbostic * Here we generate pseudo-ops that cause the assembler to put
1843224Sbostic * symbolic debugging information into the object file.
1943224Sbostic *
2043224Sbostic * University of Utah CS Dept modification history:
2143224Sbostic *
2243224Sbostic * $Log: stab.c,v $
2343224Sbostic * Revision 1.2 85/02/02 01:30:09 donn
2443224Sbostic * Don't put the 'program' name into the file; it only confuses dbx, sigh.
2543224Sbostic *
2643224Sbostic */
2743224Sbostic
2843224Sbostic #include "defs.h"
2943224Sbostic
3043224Sbostic #include <sys/types.h>
3143224Sbostic #include <a.out.h>
3243224Sbostic #include <stab.h>
3343224Sbostic
3443224Sbostic #define public
3543224Sbostic #define private static
3643224Sbostic #define and &&
3743224Sbostic #define or ||
3843224Sbostic #define not !
3943224Sbostic #define div /
4043224Sbostic #define mod %
4143224Sbostic #define nil 0
4243224Sbostic
4343224Sbostic typedef enum { false, true } Boolean;
4443224Sbostic
4543224Sbostic static char asmline[128];
4643224Sbostic int len;
4743224Sbostic extern char *malloc();
4843224Sbostic
prstab(s,code,type,loc)4943224Sbostic prstab(s, code, type, loc)
5043224Sbostic char *s, *loc;
5143224Sbostic int code, type;
5243224Sbostic {
5343224Sbostic char *locout;
5443224Sbostic
5543224Sbostic if (sdbflag) {
5643224Sbostic locout = (loc == nil) ? "0" : loc;
5743224Sbostic if (s == nil) {
5843224Sbostic sprintf(asmline, "\t.stabn\t0x%x,0,0x%x,%s\n", code, type, locout);
5943224Sbostic } else {
6043224Sbostic sprintf(asmline, "\t.stabs\t\"%s\",0x%x,0,0x%x,%s\n", s, code, type,
6143224Sbostic locout);
6243224Sbostic }
6343224Sbostic p2pass( asmline );
6443224Sbostic }
6543224Sbostic }
6643224Sbostic
filenamestab(s)6743224Sbostic filenamestab(s)
6843224Sbostic char *s;
6943224Sbostic {
7043224Sbostic sprintf(asmline,"\t.stabs\t\"%s\",0x%x,0,0,0\n", s, N_SO);
7143224Sbostic p2pass( asmline );
7243224Sbostic }
7343224Sbostic
linenostab(lineno)7443224Sbostic linenostab(lineno)
7543224Sbostic int lineno;
7643224Sbostic {
7743224Sbostic sprintf(asmline,"\t.stabd\t0x%x,0,%d\n", N_SLINE, lineno);
7843224Sbostic p2pass( asmline );
7943224Sbostic }
8043224Sbostic
8143224Sbostic /*
8243224Sbostic * Generate information for an entry point
8343224Sbostic */
8443224Sbostic
entrystab(p,class)8543224Sbostic public entrystab(p,class)
8643224Sbostic register struct Entrypoint *p;
8743224Sbostic int class;
8843224Sbostic {
8943224Sbostic int et;
9043224Sbostic Namep q;
9143224Sbostic
9243224Sbostic switch(class) {
9343224Sbostic case CLMAIN:
9443224Sbostic et=writestabtype(TYSUBR);
9543224Sbostic sprintf(asmline, "\t.stabs\t\"MAIN:F%2d\",0x%x,0,0,L%d\n",
9643224Sbostic et,N_FUN,p->entrylabel);
9743224Sbostic p2pass(asmline);
9843224Sbostic break;
9943224Sbostic
10043224Sbostic case CLBLOCK: /* May need to something with block data LATER */
10143224Sbostic break;
10243224Sbostic
10343224Sbostic default :
10443224Sbostic if( (q=p->enamep) == nil) fatal("entrystab has no nameblock");
10543224Sbostic sprintf(asmline, "\t.stabs\t\"%s:F", varstr(VL,q->varname));
10643224Sbostic len = strlen(asmline);
10743224Sbostic /* when insufficient information is around assume TYSUBR; enddcl
10843224Sbostic will fill this in*/
10943224Sbostic if(q->vtype == TYUNKNOWN || (q->vtype == TYCHAR && q->vleng == nil) ){
11043224Sbostic sprintf(asmline+len, "%2d", writestabtype(TYSUBR));
11143224Sbostic }
11243224Sbostic else addtypeinfo(q);
11343224Sbostic len += strlen(asmline+len);
11443224Sbostic sprintf(asmline+len, "\",0x%x,0,0,L%d\n",N_FUN,p->entrylabel);
11543224Sbostic p2pass(asmline);
11643224Sbostic break;
11743224Sbostic }
11843224Sbostic }
11943224Sbostic
12043224Sbostic /*
12143224Sbostic * Generate information for a symbol table (name block ) entry.
12243224Sbostic */
12343224Sbostic
namestab(sym)12443224Sbostic public namestab(sym)
12543224Sbostic Namep sym;
12643224Sbostic {
12743224Sbostic register Namep p;
12843224Sbostic char *varname, *classname;
12943224Sbostic Boolean ignore;
13043224Sbostic int vartype;
13143224Sbostic
13243224Sbostic ignore = false;
13343224Sbostic p = sym;
13443224Sbostic if(!p->vdcldone) return;
13543224Sbostic vartype = p->vtype;
13643224Sbostic varname = varstr(VL, p->varname);
13743224Sbostic switch (p->vclass) {
13843224Sbostic case CLPARAM: /* parameter (constant) */
13943224Sbostic classname = "c";
14043224Sbostic break;
14143224Sbostic
14243224Sbostic case CLVAR: /* variable */
14343224Sbostic case CLUNKNOWN:
14443224Sbostic if(p->vstg == STGARG) classname = "v";
14543224Sbostic else classname = "V";
14643224Sbostic break;
14743224Sbostic
14843224Sbostic case CLMAIN: /* main program */
14943224Sbostic case CLENTRY: /* secondary entry point */
15043224Sbostic case CLBLOCK: /* block data name*/
15143224Sbostic case CLPROC: /* external or function or subroutine */
15243224Sbostic ignore = true; /* these are put out by entrystab */
15343224Sbostic break;
15443224Sbostic
15543224Sbostic
15643224Sbostic }
15743224Sbostic if (not ignore) {
15843224Sbostic sprintf(asmline, "\t.stabs\t\"%s:%s", varname, classname);
15943224Sbostic len = strlen(asmline);
16043224Sbostic addtypeinfo(p);
16143224Sbostic len += strlen(asmline+len);
16243224Sbostic switch(p->vstg) {
16343224Sbostic
16443224Sbostic case STGUNKNOWN :
16543224Sbostic case STGCONST :
16643224Sbostic case STGEXT :
16743224Sbostic case STGINTR :
16843224Sbostic case STGSTFUNCT :
16943224Sbostic case STGLENG :
17043224Sbostic case STGNULL :
17143224Sbostic case STGREG :
17243224Sbostic case STGINIT :
17343224Sbostic sprintf(asmline+len,
17443224Sbostic "\",0x%x,0,0,0 /* don't know how to calc loc for stg %d*/ \n",
17543224Sbostic N_LSYM,p->vstg);
17643224Sbostic break;
17743224Sbostic
17843224Sbostic case STGARG :
17943224Sbostic sprintf(asmline+len,"\",0x%x,0,0,%d \n",
18043224Sbostic N_PSYM,p->vardesc.varno + ARGOFFSET );
18143224Sbostic break;
18243224Sbostic
18343224Sbostic case STGCOMMON :
18443224Sbostic sprintf(asmline+len, "\",0x%x,0,0,%d\n",
18543224Sbostic N_GSYM, p->voffset);
18643224Sbostic break;
18743224Sbostic
18843224Sbostic case STGBSS :
18943224Sbostic sprintf(asmline+len, "\",0x%x,0,0,v.%d\n",
19043224Sbostic (p->inlcomm ? N_LCSYM : N_STSYM),
19143224Sbostic p->vardesc.varno);
19243224Sbostic break;
19343224Sbostic
19443224Sbostic case STGEQUIV :
19543224Sbostic sprintf(asmline+len, "\",0x%x,0,0,%s + %d \n",
19643224Sbostic (p->inlcomm ? N_LCSYM : N_STSYM) ,
19743224Sbostic memname(STGEQUIV,p->vardesc.varno),(p->voffset)) ;
19843224Sbostic break;
19943224Sbostic
20043224Sbostic case STGAUTO :
20143224Sbostic sprintf(asmline+len, "\",0x%x,0,0,-%d \n",
20243224Sbostic N_LSYM, p->voffset);
20343224Sbostic
20443224Sbostic }
20543224Sbostic p2pass(asmline);
20643224Sbostic }
20743224Sbostic }
20843224Sbostic
20943224Sbostic static typenum[NTYPES]; /* has the given type already been defined ?*/
21043224Sbostic
writestabtype(type)21143224Sbostic private writestabtype(type)
21243224Sbostic int type;
21343224Sbostic {
21443224Sbostic char asmline[130];
21543224Sbostic static char *typename[NTYPES] =
21643224Sbostic { "unknown", "addr","integer*2", "integer", "real", "double precision",
21743224Sbostic "complex", "double complex", "logical", "char", "void", "error" };
21843224Sbostic
21943224Sbostic static int typerange[NTYPES] = { 0, 3, 2, 3, 4, 5, 6, 7, 3, 9, 10, 11 };
22043224Sbostic
22143224Sbostic /* compare with typesize[] in init.c */
22243224Sbostic static int typebounds[2] [NTYPES] ={
22343224Sbostic /* "unknown", "addr","integer*2", "integer", "real", "double precision", */
22443224Sbostic { 0 , 0 , -32768, -2147483648, 4, 8,
22543224Sbostic /* "complex", "double complex", "logical", "char", "void", "error" }; */
22643224Sbostic 8, 16, 0, 0, 0, 0 },
22743224Sbostic /* "unknown", "addr","integer*2", "integer", "real", "double precision", */
22843224Sbostic { 0 , -1, 32767, 2147483647, 0, 0,
22943224Sbostic /* "complex", "double complex", "logical", "char", "void", "error" }; */
23043224Sbostic 0, 0, 1, 127, 0, 0 }
23143224Sbostic };
23243224Sbostic
23343224Sbostic
23443224Sbostic if( type < 0 || type > NTYPES) badtype("writestabtype",type);
23543224Sbostic
23643224Sbostic if (typenum[type]) return(typenum[type]);
23743224Sbostic typenum[type] = type;
23843224Sbostic sprintf(asmline, "\t.stabs\t\"%s:t%d=r%d;%ld;%ld;\",0x%x,0,0,0 \n",
23943224Sbostic typename[type], type, typerange[type], typebounds[0][type],
24043224Sbostic typebounds[1][type], N_GSYM) ;
24143224Sbostic p2pass(asmline);
24243224Sbostic return(typenum[type]);
24343224Sbostic }
24443224Sbostic
24543224Sbostic
getbasenum(p)24643224Sbostic private getbasenum(p)
24743224Sbostic Namep p;
24843224Sbostic {
24943224Sbostic
25043224Sbostic int t;
25143224Sbostic t = p->vtype;
25243224Sbostic if( t < TYSHORT || t > TYSUBR)
25343224Sbostic dclerr("can't get dbx basetype information",p);
25443224Sbostic
25543224Sbostic if (p->vtype == TYCHAR || p->vdim != nil ) writestabtype(TYINT);
25643224Sbostic return(writestabtype(t));
25743224Sbostic }
25843224Sbostic
25943224Sbostic /*
26043224Sbostic * Generate debugging information for the given type of the given symbol.
26143224Sbostic */
26243224Sbostic
addtypeinfo(sym)26343224Sbostic private addtypeinfo(sym)
26443224Sbostic Namep sym;
26543224Sbostic {
26643224Sbostic Namep p;
26743224Sbostic int i,tnum;
26843224Sbostic char lb[20],ub[20];
26943224Sbostic
27043224Sbostic p = sym;
27143224Sbostic if (p->tag != TNAME) badtag("addtypeinfo",p->tag);
27243224Sbostic
27343224Sbostic tnum = getbasenum(p);
27443224Sbostic if(p->vdim != (struct Dimblock *) ENULL) {
27543224Sbostic
27643224Sbostic for (i = p->vdim->ndim-1; i >=0 ; --i) {
27743224Sbostic if(p->vdim->dims[i].lbaddr == ENULL) {
27846308Sbostic sprintf(lb,"%d", p->vdim->dims[i].lb->constblock.constant.ci);
27943224Sbostic }
28043224Sbostic else {
28146308Sbostic sprintf(lb,"T%d", p->vdim->dims[i].lbaddr->addrblock.memoffset->constblock.constant.ci);
28243224Sbostic }
28343224Sbostic if(p->vdim->dims[i].ubaddr == ENULL) {
28446308Sbostic sprintf(ub,"%d",p->vdim->dims[i].ub->constblock.constant.ci);
28543224Sbostic }
28643224Sbostic else {
28746308Sbostic sprintf(ub,"T%d",p->vdim->dims[i].ubaddr->addrblock.memoffset->constblock.constant.ci);
28843224Sbostic }
28943224Sbostic sprintf(asmline+len, "ar%d;%s;%s;", TYINT, lb, ub);
29043224Sbostic len += strlen(asmline+len);
29143224Sbostic }
29243224Sbostic }
29343224Sbostic if (p->vtype == TYCHAR) {
29443224Sbostic /* character type always an array(1:?) */
29543224Sbostic if( ! (p->vleng ) )
29643224Sbostic fatalstr("missing length in addtypeinfo for character variable %s", varstr(p->varname));
29743224Sbostic
29846308Sbostic if (ISCONST(p->vleng)) sprintf(ub,"%d",p->vleng->constblock.constant.ci);
29943224Sbostic else sprintf(ub,"A%d",p->vleng->addrblock.memno + ARGOFFSET);
30043224Sbostic
30143224Sbostic sprintf(asmline+len,"ar%d;1;%s;", TYINT, ub);
30243224Sbostic len += strlen(asmline+len);
30343224Sbostic }
30443224Sbostic sprintf(asmline+len, "%d",tnum);
30543224Sbostic }
306