Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

stab.c

Go to the documentation of this file.
00001 #include <string.h>
00002 #include <stdlib.h>
00003 #include "c.h"
00004 #include "stab.h"
00005 
00006 
00007 static char *currentfile;       /* current file name */
00008 static int ntypes;
00009 
00010 extern Interface sparcIR;
00011 
00012 char *stabprefix = "L";
00013 
00014 extern char *stabprefix;
00015 extern void stabblock(int, int, Symbol*);
00016 extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *);
00017 extern void stabfend(Symbol, int);
00018 extern void stabinit(char *, int, char *[]);
00019 extern void stabline(Coordinate *);
00020 extern void stabsym(Symbol);
00021 extern void stabtype(Symbol);
00022 
00023 static void asgncode(Type, int);
00024 static void dbxout(Type);
00025 static int dbxtype(Type);
00026 static int emittype(Type, int, int);
00027 
00028 /* asgncode - assign type code to ty */
00029 static void asgncode(Type ty, int lev) {
00030     if (ty->x.marked || ty->x.typeno)
00031         return;
00032     ty->x.marked = 1;
00033     switch (ty->op) {
00034     case VOLATILE: case CONST: case VOLATILE+CONST:
00035         asgncode(ty->type, lev);
00036         ty->x.typeno = ty->type->x.typeno;
00037         break;
00038     case POINTER: case FUNCTION: case ARRAY:
00039         asgncode(ty->type, lev + 1);
00040         /* fall thru */
00041     case VOID: case INT: case UNSIGNED: case FLOAT:
00042         break;
00043     case STRUCT: case UNION: {
00044         Field p;
00045         for (p = fieldlist(ty); p; p = p->link)
00046             asgncode(p->type, lev + 1);
00047         /* fall thru */
00048     case ENUM:
00049         if (ty->x.typeno == 0)
00050             ty->x.typeno = ++ntypes;
00051         if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9'))
00052             dbxout(ty);
00053         break;
00054         }
00055     default:
00056         assert(0);
00057     }
00058 }
00059 
00060 /* dbxout - output .stabs entry for type ty */
00061 static void dbxout(Type ty) {
00062     ty = unqual(ty);
00063     if (!ty->x.printed) {
00064         int col = 0;
00065         print(".stabs \""), col += 8;
00066         if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty)))
00067             print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name);
00068         print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2;
00069         emittype(ty, 0, col);
00070         print("\",%d,0,0,0\n", N_LSYM);
00071     }
00072 }
00073 
00074 /* dbxtype - emit a stabs entry for type ty, return type code */
00075 static int dbxtype(Type ty) {
00076     asgncode(ty, 0);
00077     dbxout(ty);
00078     return ty->x.typeno;
00079 }
00080 
00081 /*
00082  * emittype - emit ty's type number, emitting its definition if necessary.
00083  * Returns the output column number after emission; col is the approximate
00084  * output column before emission and is used to emit continuation lines for long
00085  * struct, union, and enum types. Continuations are not emitted for other types,
00086  * even if the definition is long. lev is the depth of calls to emittype.
00087  */
00088 static int emittype(Type ty, int lev, int col) {
00089     int tc = ty->x.typeno;
00090 
00091     if (isconst(ty) || isvolatile(ty)) {
00092         col = emittype(ty->type, lev, col);
00093         ty->x.typeno = ty->type->x.typeno;
00094         ty->x.printed = 1;
00095         return col;
00096     }
00097     if (tc == 0) {
00098         ty->x.typeno = tc = ++ntypes;
00099 /*              fprint(2,"`%t'=%d\n", ty, tc); */
00100     }
00101     print("%d", tc), col += 3;
00102     if (ty->x.printed)
00103         return col;
00104     ty->x.printed = 1;
00105     switch (ty->op) {
00106     case VOID:  /* void is defined as itself */
00107         print("=%d", tc), col += 1+3;
00108         break;
00109     case INT:
00110         if (ty == chartype) /* plain char is a subrange of itself */
00111             print("=r%d;%d;%d;", tc, ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i),
00112                 col += 2+3+2*2.408*ty->size+2;
00113         else            /* other signed ints are subranges of int */
00114             print("=r1;%D;%D;", ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i),
00115                 col += 4+2*2.408*ty->size+2;
00116         break;
00117     case UNSIGNED:
00118         if (ty == chartype) /* plain char is a subrange of itself */
00119             print("=r%d;0;%u;", tc, ty->u.sym->u.limits.max.i),
00120                 col += 2+3+2+2.408*ty->size+1;
00121         else            /* other signed ints are subranges of int */
00122             print("=r1;0;%U;", ty->u.sym->u.limits.max.i),
00123                 col += 4+2.408*ty->size+1;
00124         break;
00125     case FLOAT: /* float, double, long double get sizes, not ranges */
00126         print("=r1;%d;0;", ty->size), col += 4+1+3;
00127         break;
00128     case POINTER:
00129         print("=*"), col += 2;
00130         col = emittype(ty->type, lev + 1, col);
00131         break;
00132     case FUNCTION:
00133         print("=f"), col += 2;
00134         col = emittype(ty->type, lev + 1, col);
00135         break;
00136     case ARRAY: /* array includes subscript as an int range */
00137         if (ty->size && ty->type->size)
00138             print("=ar1;0;%d;", ty->size/ty->type->size - 1), col += 7+3+1;
00139         else
00140             print("=ar1;0;-1;"), col += 10;
00141         col = emittype(ty->type, lev + 1, col);
00142         break;
00143     case STRUCT: case UNION: {
00144         Field p;
00145         if (!ty->u.sym->defined) {
00146             print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name);
00147             col += 2+1+strlen(ty->u.sym->name)+1;
00148             break;
00149         }
00150         if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
00151             ty->x.printed = 0;
00152             break;
00153         }
00154         print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3;
00155         for (p = fieldlist(ty); p; p = p->link) {
00156             if (p->name)
00157                 print("%s:", p->name), col += strlen(p->name)+1;
00158             else
00159                 print(":"), col += 1;
00160             col = emittype(p->type, lev + 1, col);
00161             if (p->lsb)
00162                 print(",%d,%d;", 8*p->offset +
00163                     (IR->little_endian ? fieldright(p) : fieldleft(p)),
00164                     fieldsize(p));
00165             else
00166                 print(",%d,%d;", 8*p->offset, 8*p->type->size);
00167             col += 1+3+1+3+1;   /* accounts for ,%d,%d; */
00168             if (col >= 80 && p->link) {
00169                 print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
00170                 col = 8;
00171             }
00172         }
00173         print(";"), col += 1;
00174         break;
00175         }
00176     case ENUM: {
00177         Symbol *p;
00178         if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) {
00179             ty->x.printed = 0;
00180             break;
00181         }
00182         print("=e"), col += 2;
00183         for (p = ty->u.sym->u.idlist; *p; p++) {
00184             print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3;
00185             if (col >= 80 && p[1]) {
00186                 print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM);
00187                 col = 8;
00188             }
00189         }
00190         print(";"), col += 1;
00191         break;
00192         }
00193     default:
00194         assert(0);
00195     }
00196     return col;
00197 }
00198 
00199 /* stabblock - output a stab entry for '{' or '}' at level lev */
00200 void stabblock(int brace, int lev, Symbol *p) {
00201     if (brace == '{')
00202         while (*p)
00203             stabsym(*p++);
00204     if (IR == &sparcIR)
00205         print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev);
00206     else {
00207         int lab = genlabel(1);
00208         print(".stabn 0x%x,0,%d,%s%d-%s\n", brace == '{' ? N_LBRAC : N_RBRAC, lev,
00209             stabprefix, lab, cfunc->x.name);
00210         print("%s%d:\n", stabprefix, lab);
00211     }
00212 }
00213 
00214 /* stabinit - initialize stab output */
00215 void stabinit(char *file, int argc, char *argv[]) {
00216     typedef void (*Closure)(Symbol, void *);
00217     extern char *getcwd(char *, size_t);
00218 
00219     print(".stabs \"lcc4_compiled.\",0x%x,0,0,0\n", N_OPT);
00220     if (file && *file) {
00221         char buf[1024], *cwd = getcwd(buf, sizeof buf);
00222         if (cwd)
00223             print(".stabs \"%s/\",0x%x,0,3,%stext0\n", cwd, N_SO, stabprefix);
00224         print(".stabs \"%s\",0x%x,0,3,%stext0\n", file, N_SO, stabprefix);
00225         (*IR->segment)(CODE);
00226         print("%stext0:\n", stabprefix, N_SO);
00227         currentfile = file;
00228     }
00229     dbxtype(inttype);
00230     dbxtype(chartype);
00231     dbxtype(doubletype);
00232     dbxtype(floattype);
00233     dbxtype(longdouble);
00234     dbxtype(longtype);
00235     dbxtype(longlong);
00236     dbxtype(shorttype);
00237     dbxtype(signedchar);
00238     dbxtype(unsignedchar);
00239     dbxtype(unsignedlong);
00240     dbxtype(unsignedlonglong);
00241     dbxtype(unsignedshort);
00242     dbxtype(unsignedtype);
00243     dbxtype(voidtype);
00244     foreach(types, GLOBAL, (Closure)stabtype, NULL);
00245 }
00246 
00247 /* stabline - emit stab entry for source coordinate *cp */
00248 void stabline(Coordinate *cp) {
00249     if (cp->file && cp->file != currentfile) {
00250         int lab = genlabel(1);
00251         print(".stabs \"%s\",0x%x,0,0,%s%d\n", cp->file, N_SOL, stabprefix, lab);
00252         print("%s%d:\n", stabprefix, lab);
00253         currentfile = cp->file;
00254     }
00255     if (IR == &sparcIR)
00256         print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y);
00257     else {
00258         int lab = genlabel(1);
00259         print(".stabn 0x%x,0,%d,%s%d-%s\n", N_SLINE, cp->y,
00260             stabprefix, lab, cfunc->x.name);
00261         print("%s%d:\n", stabprefix, lab);
00262     }
00263 }
00264 
00265 /* stabsym - output a stab entry for symbol p */
00266 void stabsym(Symbol p) {
00267     int code, tc, sz = p->type->size;
00268 
00269     if (p->generated || p->computed)
00270         return;
00271     if (isfunc(p->type)) {
00272         print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name,
00273             p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)),
00274             N_FUN, p->x.name);
00275         return;
00276     }
00277     if (!IR->wants_argb && p->scope == PARAM && p->structarg) {
00278         assert(isptr(p->type) && isstruct(p->type->type));
00279         tc = dbxtype(p->type->type);
00280         sz = p->type->type->size;
00281     } else
00282         tc = dbxtype(p->type);
00283     if (p->sclass == AUTO && p->scope == GLOBAL || p->sclass == EXTERN) {
00284         print(".stabs \"%s:G", p->name);
00285         code = N_GSYM;
00286     } else if (p->sclass == STATIC) {
00287         print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V',
00288             tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name);
00289         return;
00290     } else if (p->sclass == REGISTER) {
00291         if (p->x.regnode) {
00292             int r = p->x.regnode->number;
00293             if (p->x.regnode->set == FREG)
00294                 r += 32;    /* floating point */
00295                 print(".stabs \"%s:%c%d\",%d,0,", p->name,
00296                     p->scope == PARAM ? 'P' : 'r', tc, N_RSYM);
00297             print("%d,%d\n", sz, r);
00298         }
00299         return;
00300     } else if (p->scope == PARAM) {
00301         print(".stabs \"%s:p", p->name);
00302         code = N_PSYM;
00303     } else if (p->scope >= LOCAL) {
00304         print(".stabs \"%s:", p->name);
00305         code = N_LSYM;
00306     } else
00307         assert(0);
00308     print("%d\",%d,0,0,%s\n", tc, code,
00309         p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0");
00310 }
00311 
00312 /* stabtype - output a stab entry for type *p */
00313 void stabtype(Symbol p) {
00314     if (p->type) {
00315         if (p->sclass == 0)
00316             dbxtype(p->type);
00317         else if (p->sclass == TYPEDEF)
00318             print(".stabs \"%s:t%d\",%d,0,0,0\n", p->name, dbxtype(p->type), N_LSYM);
00319     }
00320 }
00321 
00322 /* stabend - finalize a function */
00323 void stabfend(Symbol p, int lineno) {}
00324 
00325 /* stabend - finalize stab output */
00326 void stabend(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) {
00327     (*IR->segment)(CODE);
00328     print(".stabs \"\", %d, 0, 0,%setext\n", N_SO, stabprefix);
00329     print("%setext:\n", stabprefix);
00330 }

Generated on Thu Aug 25 12:38:15 2005 for Quake III Arena by  doxygen 1.3.9.1