stab.c (9415B)
1 #include <string.h> 2 #include <stdlib.h> 3 #include "c.h" 4 #include "stab.h" 5 6 7 static char *currentfile; /* current file name */ 8 static int ntypes; 9 10 extern Interface sparcIR; 11 12 char *stabprefix = "L"; 13 14 extern char *stabprefix; 15 extern void stabblock(int, int, Symbol*); 16 extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *); 17 extern void stabfend(Symbol, int); 18 extern void stabinit(char *, int, char *[]); 19 extern void stabline(Coordinate *); 20 extern void stabsym(Symbol); 21 extern void stabtype(Symbol); 22 23 static void asgncode(Type, int); 24 static void dbxout(Type); 25 static int dbxtype(Type); 26 static int emittype(Type, int, int); 27 28 /* asgncode - assign type code to ty */ 29 static void asgncode(Type ty, int lev) { 30 if (ty->x.marked || ty->x.typeno) 31 return; 32 ty->x.marked = 1; 33 switch (ty->op) { 34 case VOLATILE: case CONST: case VOLATILE+CONST: 35 asgncode(ty->type, lev); 36 ty->x.typeno = ty->type->x.typeno; 37 break; 38 case POINTER: case FUNCTION: case ARRAY: 39 asgncode(ty->type, lev + 1); 40 /* fall thru */ 41 case VOID: case INT: case UNSIGNED: case FLOAT: 42 break; 43 case STRUCT: case UNION: { 44 Field p; 45 for (p = fieldlist(ty); p; p = p->link) 46 asgncode(p->type, lev + 1); 47 /* fall thru */ 48 case ENUM: 49 if (ty->x.typeno == 0) 50 ty->x.typeno = ++ntypes; 51 if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) 52 dbxout(ty); 53 break; 54 } 55 default: 56 assert(0); 57 } 58 } 59 60 /* dbxout - output .stabs entry for type ty */ 61 static void dbxout(Type ty) { 62 ty = unqual(ty); 63 if (!ty->x.printed) { 64 int col = 0; 65 print(".stabs \""), col += 8; 66 if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty))) 67 print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name); 68 print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2; 69 emittype(ty, 0, col); 70 print("\",%d,0,0,0\n", N_LSYM); 71 } 72 } 73 74 /* dbxtype - emit a stabs entry for type ty, return type code */ 75 static int dbxtype(Type ty) { 76 asgncode(ty, 0); 77 dbxout(ty); 78 return ty->x.typeno; 79 } 80 81 /* 82 * emittype - emit ty's type number, emitting its definition if necessary. 83 * Returns the output column number after emission; col is the approximate 84 * output column before emission and is used to emit continuation lines for long 85 * struct, union, and enum types. Continuations are not emitted for other types, 86 * even if the definition is long. lev is the depth of calls to emittype. 87 */ 88 static int emittype(Type ty, int lev, int col) { 89 int tc = ty->x.typeno; 90 91 if (isconst(ty) || isvolatile(ty)) { 92 col = emittype(ty->type, lev, col); 93 ty->x.typeno = ty->type->x.typeno; 94 ty->x.printed = 1; 95 return col; 96 } 97 if (tc == 0) { 98 ty->x.typeno = tc = ++ntypes; 99 /* fprint(2,"`%t'=%d\n", ty, tc); */ 100 } 101 print("%d", tc), col += 3; 102 if (ty->x.printed) 103 return col; 104 ty->x.printed = 1; 105 switch (ty->op) { 106 case VOID: /* void is defined as itself */ 107 print("=%d", tc), col += 1+3; 108 break; 109 case INT: 110 if (ty == chartype) /* plain char is a subrange of itself */ 111 print("=r%d;%d;%d;", tc, ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i), 112 col += 2+3+2*2.408*ty->size+2; 113 else /* other signed ints are subranges of int */ 114 print("=r1;%D;%D;", ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i), 115 col += 4+2*2.408*ty->size+2; 116 break; 117 case UNSIGNED: 118 if (ty == chartype) /* plain char is a subrange of itself */ 119 print("=r%d;0;%u;", tc, ty->u.sym->u.limits.max.i), 120 col += 2+3+2+2.408*ty->size+1; 121 else /* other signed ints are subranges of int */ 122 print("=r1;0;%U;", ty->u.sym->u.limits.max.i), 123 col += 4+2.408*ty->size+1; 124 break; 125 case FLOAT: /* float, double, long double get sizes, not 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 if (!ty->u.sym->defined) { 146 print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name); 147 col += 2+1+strlen(ty->u.sym->name)+1; 148 break; 149 } 150 if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) { 151 ty->x.printed = 0; 152 break; 153 } 154 print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3; 155 for (p = fieldlist(ty); p; p = p->link) { 156 if (p->name) 157 print("%s:", p->name), col += strlen(p->name)+1; 158 else 159 print(":"), col += 1; 160 col = emittype(p->type, lev + 1, col); 161 if (p->lsb) 162 print(",%d,%d;", 8*p->offset + 163 (IR->little_endian ? fieldright(p) : fieldleft(p)), 164 fieldsize(p)); 165 else 166 print(",%d,%d;", 8*p->offset, 8*p->type->size); 167 col += 1+3+1+3+1; /* accounts for ,%d,%d; */ 168 if (col >= 80 && p->link) { 169 print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM); 170 col = 8; 171 } 172 } 173 print(";"), col += 1; 174 break; 175 } 176 case ENUM: { 177 Symbol *p; 178 if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) { 179 ty->x.printed = 0; 180 break; 181 } 182 print("=e"), col += 2; 183 for (p = ty->u.sym->u.idlist; *p; p++) { 184 print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3; 185 if (col >= 80 && p[1]) { 186 print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM); 187 col = 8; 188 } 189 } 190 print(";"), col += 1; 191 break; 192 } 193 default: 194 assert(0); 195 } 196 return col; 197 } 198 199 /* stabblock - output a stab entry for '{' or '}' at level lev */ 200 void stabblock(int brace, int lev, Symbol *p) { 201 if (brace == '{') 202 while (*p) 203 stabsym(*p++); 204 if (IR == &sparcIR) 205 print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev); 206 else { 207 int lab = genlabel(1); 208 print(".stabn 0x%x,0,%d,%s%d-%s\n", brace == '{' ? N_LBRAC : N_RBRAC, lev, 209 stabprefix, lab, cfunc->x.name); 210 print("%s%d:\n", stabprefix, lab); 211 } 212 } 213 214 /* stabinit - initialize stab output */ 215 void stabinit(char *file, int argc, char *argv[]) { 216 typedef void (*Closure)(Symbol, void *); 217 extern char *getcwd(char *, size_t); 218 219 print(".stabs \"lcc4_compiled.\",0x%x,0,0,0\n", N_OPT); 220 if (file && *file) { 221 char buf[1024], *cwd = getcwd(buf, sizeof buf); 222 if (cwd) 223 print(".stabs \"%s/\",0x%x,0,3,%stext0\n", cwd, N_SO, stabprefix); 224 print(".stabs \"%s\",0x%x,0,3,%stext0\n", file, N_SO, stabprefix); 225 (*IR->segment)(CODE); 226 print("%stext0:\n", stabprefix, N_SO); 227 currentfile = file; 228 } 229 dbxtype(inttype); 230 dbxtype(chartype); 231 dbxtype(doubletype); 232 dbxtype(floattype); 233 dbxtype(longdouble); 234 dbxtype(longtype); 235 dbxtype(longlong); 236 dbxtype(shorttype); 237 dbxtype(signedchar); 238 dbxtype(unsignedchar); 239 dbxtype(unsignedlong); 240 dbxtype(unsignedlonglong); 241 dbxtype(unsignedshort); 242 dbxtype(unsignedtype); 243 dbxtype(voidtype); 244 foreach(types, GLOBAL, (Closure)stabtype, NULL); 245 } 246 247 /* stabline - emit stab entry for source coordinate *cp */ 248 void stabline(Coordinate *cp) { 249 if (cp->file && cp->file != currentfile) { 250 int lab = genlabel(1); 251 print(".stabs \"%s\",0x%x,0,0,%s%d\n", cp->file, N_SOL, stabprefix, lab); 252 print("%s%d:\n", stabprefix, lab); 253 currentfile = cp->file; 254 } 255 if (IR == &sparcIR) 256 print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y); 257 else { 258 int lab = genlabel(1); 259 print(".stabn 0x%x,0,%d,%s%d-%s\n", N_SLINE, cp->y, 260 stabprefix, lab, cfunc->x.name); 261 print("%s%d:\n", stabprefix, lab); 262 } 263 } 264 265 /* stabsym - output a stab entry for symbol p */ 266 void stabsym(Symbol p) { 267 int code, tc, sz = p->type->size; 268 269 if (p->generated || p->computed) 270 return; 271 if (isfunc(p->type)) { 272 print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, 273 p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)), 274 N_FUN, p->x.name); 275 return; 276 } 277 if (!IR->wants_argb && p->scope == PARAM && p->structarg) { 278 assert(isptr(p->type) && isstruct(p->type->type)); 279 tc = dbxtype(p->type->type); 280 sz = p->type->type->size; 281 } else 282 tc = dbxtype(p->type); 283 if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) { 284 print(".stabs \"%s:G", p->name); 285 code = N_GSYM; 286 } else if (p->sclass == STATIC) { 287 print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V', 288 tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name); 289 return; 290 } else if (p->sclass == REGISTER) { 291 if (p->x.regnode) { 292 int r = p->x.regnode->number; 293 if (p->x.regnode->set == FREG) 294 r += 32; /* floating point */ 295 print(".stabs \"%s:%c%d\",%d,0,", p->name, 296 p->scope == PARAM ? 'P' : 'r', tc, N_RSYM); 297 print("%d,%d\n", sz, r); 298 } 299 return; 300 } else if (p->scope == PARAM) { 301 print(".stabs \"%s:p", p->name); 302 code = N_PSYM; 303 } else if (p->scope >= LOCAL) { 304 print(".stabs \"%s:", p->name); 305 code = N_LSYM; 306 } else 307 assert(0); 308 print("%d\",%d,0,0,%s\n", tc, code, 309 p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0"); 310 } 311 312 /* stabtype - output a stab entry for type *p */ 313 void stabtype(Symbol p) { 314 if (p->type) { 315 if (p->sclass == 0) 316 dbxtype(p->type); 317 else if (p->sclass == TYPEDEF) 318 print(".stabs \"%s:t%d\",%d,0,0,0\n", p->name, dbxtype(p->type), N_LSYM); 319 } 320 } 321 322 /* stabend - finalize a function */ 323 void stabfend(Symbol p, int lineno) {} 324 325 /* stabend - finalize stab output */ 326 void stabend(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) { 327 (*IR->segment)(CODE); 328 print(".stabs \"\", %d, 0, 0,%setext\n", N_SO, stabprefix); 329 print("%setext:\n", stabprefix); 330 }