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