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