|
|
1.1 ! root 1: /* C compiler: UNIX code generator ! 2: * ! 3: * Outputs `stab' entries for the UNIX dbx debugger, ! 4: * if -g is specified. ! 5: */ ! 6: ! 7: static char *currentfile; /* current file name */ ! 8: static int ntypes; ! 9: ! 10: dclproto(static void stabblock,(int, int, Symbol*)); ! 11: dclproto(static void stabfend,(Symbol, int)); ! 12: dclproto(static void stabinit,(char *, int, char *[])); ! 13: dclproto(static void stabline,(Coordinate *)); ! 14: dclproto(static void stabsym,(Symbol)); ! 15: dclproto(static void stabtype,(Symbol)); ! 16: ! 17: dclproto(static void asgncode,(Type, int)); ! 18: dclproto(static void dbxout,(Type)); ! 19: dclproto(static int dbxtype,(Type)); ! 20: dclproto(static int emittype,(Type, int, int)); ! 21: ! 22: /* asgncode - assign type code to ty */ ! 23: static void asgncode(ty, lev) Type ty; { ! 24: if (ty->x.marked || ty->x.typeno) ! 25: return; ! 26: /* fprint(2, "asgncode(`%t',%d) ty->x.typeno=0x%x\n", ty, lev, ty->x.typeno); */ ! 27: ty->x.marked = 1; ! 28: switch (ty->op) { ! 29: case VOLATILE: case CONST: case VOLATILE+CONST: ! 30: asgncode(ty->type, lev); ! 31: ty->x.typeno = ty->type->x.typeno; ! 32: break; ! 33: case POINTER: case FUNCTION: case ARRAY: ! 34: asgncode(ty->type, lev + 1); ! 35: /* fall thru */ ! 36: case VOID: case CHAR: case SHORT: case INT: case UNSIGNED: ! 37: case FLOAT: case DOUBLE: ! 38: break; ! 39: case STRUCT: case UNION: { ! 40: Field p; ! 41: for (p = fieldlist(ty); p; p = p->link) ! 42: asgncode(p->type, lev + 1); ! 43: /* fall thru */ ! 44: case ENUM: ! 45: if (ty->x.typeno == 0) { ! 46: ty->x.typeno = ++ntypes; ! 47: /* fprint(2,"`%t'=%d in asgncode\n", ty, ntypes); */ ! 48: } ! 49: if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) ! 50: dbxout(ty); ! 51: break; ! 52: } ! 53: default: ! 54: assert(0); ! 55: } ! 56: } ! 57: ! 58: /* dbxout - output .stabs entry for type ty */ ! 59: static void dbxout(ty) Type ty; { ! 60: ty = unqual(ty); ! 61: if (!ty->x.printed) { ! 62: int col = 0; ! 63: print(".stabs \""), col += 8; ! 64: if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty))) ! 65: print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name); ! 66: print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2; ! 67: emittype(ty, 0, col); ! 68: print("\",%d,0,0,0\n", N_LSYM); ! 69: } ! 70: } ! 71: ! 72: /* dbxtype - emit a stabs entry for type ty, return type code */ ! 73: static int dbxtype(ty) Type ty; { ! 74: asgncode(ty, 0); ! 75: dbxout(ty); ! 76: return ty->x.typeno; ! 77: } ! 78: ! 79: /* ! 80: * emittype - emit ty's type number, emitting its definition if necessary. ! 81: * Returns the output column number after emission; col is the approximate ! 82: * output column before emission and is used to emit continuation lines for long ! 83: * struct, union, and enum types. Continuations are not emitted for other types, ! 84: * even if the definition is long. lev is the depth of calls to emittype. ! 85: */ ! 86: static int emittype(ty, lev, col) Type ty; { ! 87: int tc = ty->x.typeno; ! 88: ! 89: if (isconst(ty) || isvolatile(ty)) { ! 90: col = emittype(ty->type, lev, col); ! 91: ty->x.typeno = ty->type->x.typeno; ! 92: ty->x.printed = 1; ! 93: return col; ! 94: } ! 95: if (tc == 0) { ! 96: ty->x.typeno = tc = ++ntypes; ! 97: /* fprint(2,"`%t'=%d\n", ty, tc); */ ! 98: } ! 99: print("%d", tc), col += 3; ! 100: if (ty->x.printed) ! 101: return col; ! 102: ty->x.printed = 1; ! 103: switch (ty->op) { ! 104: case VOID: /* void is defined as itself */ ! 105: print("=%d", tc), col += 1+3; ! 106: break; ! 107: case CHAR: /* unsigned char is a subrange of int */ ! 108: if (ty == unsignedchar) ! 109: print("=r1;0;255;"), col += 10; ! 110: else /* following pcc, char is a subrange of itself */ ! 111: print("=r%d;-128;127;", tc), col += 2+3+10; ! 112: break; ! 113: case SHORT: /* short is a subrange of int */ ! 114: if (ty == unsignedshort) ! 115: print("=r1;0;65535;"), col += 12; ! 116: else /* signed */ ! 117: print("=r1;-32768;32767;"), col += 17; ! 118: break; ! 119: case INT: /* int is a subrange of itself */ ! 120: print("=r1;%d;%d;", INT_MIN, INT_MAX), col += 4+11+1+10+1; ! 121: break; ! 122: case UNSIGNED: /* unsigned is a subrange of int */ ! 123: print("=r1;0;-1;"), col += 9; ! 124: break; ! 125: case FLOAT: case DOUBLE: /* float, double get sizes instead of ranges */ ! 126: print("=r1;%d;0;", ty->size), col += 4+1+3; ! 127: break; ! 128: case POINTER: ! 129: print("=*"), col += 2; ! 130: col = emittype(ty->type, lev + 1, col); ! 131: break; ! 132: case FUNCTION: ! 133: print("=f"), col += 2; ! 134: col = emittype(ty->type, lev + 1, col); ! 135: break; ! 136: case ARRAY: /* array includes subscript as an int range */ ! 137: if (ty->size && ty->type->size) ! 138: print("=ar1;0;%d;", ty->size/ty->type->size - 1), col += 7+3+1; ! 139: else ! 140: print("=ar1;0;-1;"), col += 10; ! 141: col = emittype(ty->type, lev + 1, col); ! 142: break; ! 143: case STRUCT: case UNION: { ! 144: Field p; ! 145: #ifdef sun ! 146: if (!ty->u.sym->defined) { ! 147: print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name); ! 148: col += 2+1+strlen(ty->u.sym->name)+1; ! 149: break; ! 150: } ! 151: #endif ! 152: if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) { ! 153: ty->x.printed = 0; ! 154: break; ! 155: } ! 156: print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3; ! 157: for (p = fieldlist(ty); p; p = p->link) { ! 158: if (p->name) ! 159: print("%s:", p->name), col += strlen(p->name)+1; ! 160: else ! 161: print(":"), col += 1; ! 162: col = emittype(p->type, lev + 1, col); ! 163: if (p->lsb) ! 164: print(",%d,%d;", 8*p->offset + ! 165: (IR->little_endian ? fieldright(p) : fieldleft(p)), ! 166: fieldsize(p)); ! 167: else ! 168: print(",%d,%d;", 8*p->offset, 8*p->type->size); ! 169: col += 1+3+1+3+1; /* accounts for ,%d,%d; */ ! 170: #if mc68020 || mc68030 || sparc ! 171: if (col >= 80 && p->link) { ! 172: print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM); ! 173: col = 8; ! 174: } ! 175: #endif ! 176: } ! 177: print(";"), col += 1; ! 178: break; ! 179: } ! 180: case ENUM: { ! 181: Symbol *p; ! 182: if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) { ! 183: ty->x.printed = 0; ! 184: break; ! 185: } ! 186: print("=e"), col += 2; ! 187: for (p = ty->u.sym->u.idlist; *p; p++) { ! 188: print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3; ! 189: #if mc68020 || mc68030 || sparc ! 190: if (col >= 80 && p[1]) { ! 191: print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM); ! 192: col = 8; ! 193: } ! 194: #endif ! 195: } ! 196: print(";"), col += 1; ! 197: break; ! 198: } ! 199: default: ! 200: assert(0); ! 201: } ! 202: return col; ! 203: } ! 204: ! 205: /* stabblock - output a stab entry for '{' or '}' at level lev */ ! 206: static void stabblock(brace, lev, p) Symbol *p; { ! 207: if (brace == '{') ! 208: while (*p) ! 209: stabsym(*p++); ! 210: print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev); ! 211: } ! 212: ! 213: /* stabfend - end of function p */ ! 214: static void stabfend(p, line) Symbol p; {} ! 215: ! 216: /* stabinit - initialize stab output */ ! 217: static void stabinit(file, argc, argv) char *file, *argv[]; { ! 218: dclproto(typedef void (*Closure),(Symbol, Generic)); ! 219: ! 220: if (file && *file) { ! 221: (*IR->segment)(CODE); ! 222: print("Ltext:.stabs \"%s\",0x%x,0,0,Ltext\n", file, N_SO); ! 223: currentfile = file; ! 224: } ! 225: stabtype(inttype->u.sym); ! 226: stabtype(chartype->u.sym); ! 227: foreach(types, 0, (Closure)stabtype, (Generic)0); ! 228: foreach(types, GLOBAL, (Closure)stabtype, (Generic)0); ! 229: } ! 230: ! 231: /* stabline - emit stab entry for source coordinate *cp */ ! 232: static void stabline(cp) Coordinate *cp; { ! 233: if (cp->file && cp->file != currentfile) { ! 234: int lab = genlabel(1); ! 235: print("L%d: .stabs \"%s\",0x%x,0,0,L%d\n", lab, ! 236: cp->file, N_SOL, lab); ! 237: currentfile = cp->file; ! 238: } ! 239: print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y); ! 240: } ! 241: ! 242: /* stabsym - output a stab entry for symbol p */ ! 243: static void stabsym(p) Symbol p; { ! 244: int code, tc, sz = p->type->size; ! 245: ! 246: if (p->generated || p->computed) ! 247: return; ! 248: if (isfunc(p->type)) { ! 249: print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, ! 250: p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)), ! 251: N_FUN, p->x.name); ! 252: return; ! 253: } ! 254: if (IR->no_argb && p->scope == PARAM && p->structarg) { ! 255: assert(isptr(p->type) && isstruct(p->type->type)); ! 256: tc = dbxtype(p->type->type); ! 257: sz = p->type->type->size; ! 258: } else ! 259: tc = dbxtype(p->type); ! 260: if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) { ! 261: print(".stabs \"%s:G", p->name); ! 262: code = N_GSYM; ! 263: } else if (p->sclass == STATIC) { ! 264: print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V', ! 265: tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name); ! 266: return; ! 267: } else if (isregvar(p)) { ! 268: print(".stabs \"%s:r%d\",%d,0,", p->name, tc, N_RSYM); ! 269: #ifdef vax ! 270: print("0,%s\n", p->x.name); ! 271: #endif ! 272: #if mc68020 || mc68030 || NeXT ! 273: print("0,%s%s\n", isptr(p->type) ? "8+" : "", p->x.name); ! 274: #endif ! 275: #ifdef sparc ! 276: { int r = p->x.regvar->x.regnode->regnum; ! 277: switch (p->x.name[0]) { ! 278: case 'r': break; ! 279: case 'f': r += 32; break; ! 280: default: assert(0); ! 281: } ! 282: print("%d,%d\n", sz, r); ! 283: } ! 284: #endif ! 285: return; ! 286: } else if (p->scope == PARAM) { ! 287: print(".stabs \"%s:p", p->name); ! 288: code = N_PSYM; ! 289: } else if (p->scope >= LOCAL) { ! 290: print(".stabs \"%s:", p->name); ! 291: code = N_LSYM; ! 292: } else ! 293: assert(0); ! 294: print("%d\",%d,0,0,%s\n", tc, code, p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0"); ! 295: } ! 296: ! 297: /* stabtype - output a stab entry for type *p */ ! 298: static void stabtype(p) Symbol p; { ! 299: if (p->type) { ! 300: if (p->sclass == 0) ! 301: dbxtype(p->type); ! 302: else if (p->sclass == TYPEDEF) ! 303: print(".stabs \"%s:t%d\",%d,0,0,0\n", p->name, dbxtype(p->type), N_LSYM); ! 304: } ! 305: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.