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