|
|
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: * -DV9 selects 9th edition stab format. ! 6: */ ! 7: #include "c.h" ! 8: ! 9: #ifdef vax ! 10: #include </usr/include/stab.h> ! 11: #ifndef V9 ! 12: #include <stabbsd.c> ! 13: #else ! 14: int glevel = 1; ! 15: static char *currentfile; /* current file name */ ! 16: ! 17: dclproto(static void emittype,(int desc, int s, Type ty, char *str)); ! 18: dclproto(extern long time,(long *)); ! 19: ! 20: /* emittype - emit p's type */ ! 21: static void emittype(desc, s, ty, str) Type ty; char *str; { ! 22: ty = unqual(ty); ! 23: switch (ty->op) { ! 24: case CHAR: desc |= (ty == unsignedchar ? 12 : 2); break; ! 25: case SHORT: desc |= (ty == unsignedshort ? 13 : 3); break; ! 26: case INT: desc |= 4; break; ! 27: case UNSIGNED: desc |= 14; break; ! 28: case FLOAT: desc |= 6; break; ! 29: case DOUBLE: desc |= 7; break; ! 30: case STRUCT: case UNION: case ENUM: ! 31: if (ty->op == STRUCT) ! 32: desc |= 8; ! 33: else if (ty->op == UNION) ! 34: desc |= 9; ! 35: else ! 36: desc |= 10; ! 37: print("0x%x,%s\n", desc, str); ! 38: if (glevel > 1) ! 39: if (*ty->u.sym->name >= '0' && *ty->u.sym->name <= '9') ! 40: print(".stabs \"%s$%d.%s\",0x%x,0,0,0\n", ty->u.sym->src.file, ! 41: ty->u.sym->src.y, ty->u.sym->name, N_TYID); ! 42: else ! 43: print(".stabs \"%s\",0x%x,0,0,0\n", ty->u.sym->name, N_TYID); ! 44: return; ! 45: case ARRAY: ! 46: emittype(desc | (3<<s), s + 2, ty->type, str); ! 47: if (glevel > 1) ! 48: print(".stabn 0x%x,0,0,%d\n", N_DIM, ty->size/ty->type->size); ! 49: return; ! 50: case POINTER: ! 51: emittype(desc | (1<<s), s + 2, ty->type, str); ! 52: return; ! 53: case FUNCTION: ! 54: emittype(desc | (2<<s), s + 2, ty->type, str); ! 55: return; ! 56: case VOID: desc |= 16; break; ! 57: default: break; ! 58: } ! 59: print("0x%x,%s\n", desc, str); ! 60: } ! 61: ! 62: /* stabblock - output a stab entry for '{' or '}' at level lev */ ! 63: void stabblock(brace, lev, p) Symbol *p; { ! 64: if (brace == '}') ! 65: while (*p) ! 66: stabsym(*p++); ! 67: print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev); ! 68: } ! 69: ! 70: /* stabend - finalize stab output */ ! 71: void stabend(cp, p, cpp, sp, syms) Coordinate *cp; Symbol p, *sp, *syms; Coordinate **cpp; { ! 72: &p; &cpp; &sp; &syms; ! 73: if (glevel == 0) ! 74: return; ! 75: if (cp->file && *cp->file) { ! 76: segment(CODE); ! 77: print("Lend:.stabs \"%s\",0x%x,0,%d,Lend\n", cp->file, N_ESO, cp->y); ! 78: } ! 79: } ! 80: ! 81: /* stabfend - end of function p */ ! 82: void stabfend(p, line) Symbol p; { ! 83: int lab; ! 84: ! 85: if (glevel <= 1) ! 86: return; ! 87: lab = genlabel(1); ! 88: print(".stabn 0x%x,0,%d,L%d\n", N_RFUN, line, p->u.f.label); ! 89: print("L%d:.stabs \"%s\",0x%x,0,%d,L%d\n", lab, ! 90: p->name, N_EFUN, line, lab); ! 91: } ! 92: ! 93: /* stabinit - initialize stab output */ ! 94: void stabinit(file, argc, argv) char *file, *argv[]; { ! 95: if (glevel == 0) ! 96: return; ! 97: if (file && *file) { ! 98: segment(CODE); ! 99: print("Ltext:.stabs \"%s\",0x%x,0,0,Ltext\n", file, N_SO); ! 100: print(".stabs \"rcc\",0x%x,0,17665,%d\n", N_VER, time(0)); ! 101: currentfile = file; ! 102: } ! 103: } ! 104: ! 105: /* stabline - emit stab entry for source coordinate *cp */ ! 106: void stabline(cp) Coordinate *cp; { ! 107: if (glevel <= 1) ! 108: return; ! 109: if (cp->file && cp->file != currentfile) { ! 110: int lab = genlabel(1); ! 111: print("L%d: .stabs \"%s\",0x%x,0,%d,L%d\n", lab, ! 112: cp->file, N_SOL, line, lab); ! 113: currentfile = cp->file; ! 114: } ! 115: print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y); ! 116: } ! 117: ! 118: /* stabsym - output a stab entry for symbol p */ ! 119: void stabsym(p) Symbol p; { ! 120: char buf[100], *adr = p->x.name; ! 121: ! 122: if (p->generated || p->computed) ! 123: return; ! 124: print(".stabs \"%s\",", p->name); ! 125: if (isfunc(p->type)) { ! 126: print("0x%x,0,0x%x,_%s\n", N_FUN, p->u.f.pt[0].y, p->name); ! 127: print(".stabs \"%s\",0x%x,0,", p->name, ! 128: p->sclass == STATIC ? N_STFUN : N_GSYM); ! 129: adr = "0"; ! 130: } else if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) { ! 131: print("0x%x,0,", N_GSYM); ! 132: adr = "0"; ! 133: } else if (p->sclass == STATIC) ! 134: print("0x%x,0,", p->u.seg == BSS ? N_LCSYM : N_STSYM); ! 135: else if (p->scope == PARAM) ! 136: print("0x%x,0,", isregvar(p) ? N_RSYM : N_PSYM); ! 137: else if (p->scope >= LOCAL) { ! 138: print("0x%x,0,", isregvar(p) ? N_RSYM : N_LSYM); ! 139: if (!isregvar(p)) ! 140: adr = p->x.name + 1; /* skip - sign */ ! 141: } else ! 142: assert(0); ! 143: emittype(0, 5, p->type, adr); ! 144: } ! 145: ! 146: /* stabtype - output a stab entry for type name, ty */ ! 147: void stabtype(p) Symbol p; { ! 148: char *name = p->name; ! 149: ! 150: if (p->sclass || p->type == 0 || glevel <= 1) ! 151: return; ! 152: if (*p->name >= '0' && *p->name <= '9') ! 153: name = stringf("%s$%d.%s", p->src.file, p->src.y, p->name); ! 154: switch (p->type->op) { ! 155: case STRUCT: case UNION: { ! 156: Field q; ! 157: print(".stabs \"%s\",0x%x,0,%d,0\n", name, N_BSTR, ! 158: p->type->op == STRUCT ? 8 : 9); ! 159: for (q = fieldlist(p->type); q; q = q->link) { ! 160: print(".stabs \"%s\",", q->name ? q->name : ""); ! 161: if (q->to) ! 162: print("0x%x,0,0x%x,%d\n", N_SFLD, ! 163: fieldsize(q)<<5|(q->type == inttype ? 4 : 14), ! 164: 8*q->offset + q->from); ! 165: else { ! 166: print("0x%x,0,", N_SSYM); ! 167: emittype(0, 5, q->type, stringd(q->offset)); ! 168: } ! 169: } ! 170: print(".stabs \"%s\",0x%x,0,%d,%d\n", name, N_ESTR, ! 171: p->type->op == STRUCT ? 8 : 9, p->type->size); ! 172: break; ! 173: } ! 174: case ENUM: { ! 175: Symbol *q; ! 176: print(".stabs \"%s\",0x%x,0,10,0\n", name, N_BSTR); ! 177: for (q = p->u.idlist; *q; q++) ! 178: print(".stabs \"%s\",0x%x,0,11,%d\n", (*q)->name, ! 179: N_SSYM, (*q)->u.value); ! 180: print(".stabs \"%s\",0x%x,0,10,%d\n", name, N_ESTR, ! 181: p->type->size); ! 182: break; ! 183: } ! 184: } ! 185: } ! 186: #endif ! 187: #else ! 188: #include "stabstub.c" ! 189: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.