|
|
1.1 ! root 1: #include "symtab.pri" ! 2: #include "dtype.pri" ! 3: #include "symbol.h" ! 4: #include "srctext.pub" ! 5: #include "phrase.pub" ! 6: #include "format.pub" ! 7: #include "core.pub" ! 8: SRCFILE("symtab.c") ! 9: ! 10: int FunctionGathered, UTypeGathered, FunctionStubs, UTypeStubs; ! 11: int IdToSymCalls, StrCmpCalls; ! 12: ! 13: UType *SymTab::utypelist() { return utype; } ! 14: ! 15: int HASHF(register char *s) ! 16: { ! 17: register unsigned h = 0; ! 18: while( *s ) h = (h<<1)^*(s++); ! 19: return h % HASH; ! 20: } ! 21: ! 22: int nccdemangle(char **text, char *classname) ! 23: { ! 24: register char *cp = *text; ! 25: if (!classname && !strncmp(cp, "__", 2) ) { // Locals ! 26: cp += 2; ! 27: if (*cp >= '0' && *cp <= '9') { ! 28: do ! 29: cp++; ! 30: while (*cp >= '0' && *cp <= '9'); ! 31: *text = cp; ! 32: return 1; ! 33: } ! 34: } ! 35: cp++; ! 36: while (*cp) { ! 37: if (*cp == '_' && cp[1] == '_') { ! 38: if (cp[2] == 'F') { // Functions ! 39: *cp = 0; ! 40: return 1; ! 41: } else if (cp[2] >= '0' && cp[2] <= '9') { // Class members ! 42: *cp = 0; ! 43: cp += 2; ! 44: int nchar = 0; ! 45: int ndigits = 0; ! 46: do { ! 47: nchar = nchar * 10 + *cp - '0'; ! 48: ndigits++; ! 49: cp++; ! 50: } while (*cp >= '0' && *cp <= '9'); ! 51: if (!classname || strlen(classname) != nchar || ! 52: strncmp(cp, classname, nchar)) { ! 53: static char proto[256]; ! 54: strncpy(proto,cp,nchar); ! 55: strcpy(proto+nchar, "::"); ! 56: strcat(proto, *text); ! 57: strcpy(*text, proto); ! 58: if (--ndigits) { ! 59: cp += nchar; ! 60: while (ndigits--) ! 61: *--cp = 0; ! 62: } ! 63: } ! 64: return 1; ! 65: } ! 66: } ! 67: cp++; ! 68: } ! 69: return 0; ! 70: } ! 71: ! 72: int ccdemangle(char **text, char *classname) ! 73: { ! 74: register char *cp = *text; ! 75: if (*cp++ != '_') ! 76: return 0; ! 77: if (classname) { ! 78: int l = strlen(classname); ! 79: if (!strncmp(cp, classname, l) && cp[l] == '_') { ! 80: *text = &cp[l+1]; ! 81: return 1; ! 82: } ! 83: } else if (!strncmp(cp, "au", 2)) { ! 84: cp += 2; ! 85: while (*cp >= '0' && *cp <= '9') ! 86: cp++; ! 87: if (*cp++ == '_') { ! 88: *text = cp; ! 89: return 1; ! 90: } ! 91: } ! 92: return 0; ! 93: } ! 94: ! 95: void SymTab::uncfront(Var *v, char *classname ) ! 96: { ! 97: for( ; v; v = (Var*)v->rsib ) { ! 98: if (!ccdemangle(&v->_text, classname)) ! 99: nccdemangle(&v->_text, classname); ! 100: } ! 101: } ! 102: ! 103: SSet::SSet(char a) ! 104: { ! 105: v[0] = a; ! 106: v[1] = 0; ! 107: } ! 108: ! 109: SSet::SSet(char a, char b, char c, char d, char e, char f, char g ) ! 110: { ! 111: v[0] = a; v[1] = b; v[2] = c; v[3] = d; ! 112: v[4] = e; v[5] = f; v[6] = g; v[7] = 0; ! 113: } ! 114: ! 115: char *DiscName(UDisc d) ! 116: { ! 117: switch( d ){ ! 118: case U_ARG: return "arg"; ! 119: case U_AUT: return "aut"; ! 120: case U_REG: return "reg"; ! 121: case U_STA: return "sta"; ! 122: case U_FST: return "Sta"; ! 123: case U_GLB: return "Glb"; ! 124: default: return Name("U_%d",d); ! 125: } ! 126: } ! 127: ! 128: char *SymTab::stabpath() { OK("SymTab::stabpath"); return _core->stabpath(); } ! 129: char *SymTab::warn() { OK("SymTab::warn"); return _warn; } ! 130: Pad *SymTab::pad() { OK(0); return _pad; } ! 131: ! 132: void SymTab::showutype(UType *u) // cf Var.showutype(UTpe*) ! 133: { ! 134: trace("%d.showutype(%d))", this, u); VOK; ! 135: u->show(LEAVE, SELECTLINE); ! 136: } ! 137: ! 138: void SymTab::banner() ! 139: { ! 140: trace("%d.banner()", this); VOK; ! 141: if( !_pad ) return; ! 142: _pad->banner("User Defined Types: %s", _core->procpath()); ! 143: _pad->name("Types %s", basename(_core->procpath())); ! 144: _pad->options(TRUNCATE); ! 145: Menu m; ! 146: Action a = (Action)&SymTab::showutype; ! 147: char *index(char*,char); ! 148: for( UType *u = utype; u; u = (UType *)u->rsib ){ ! 149: if( u->type.isstrun() ) ! 150: m.sort(sf("%s\240",u->text()), a, (long) u); ! 151: } ! 152: _pad->menu(m); ! 153: } ! 154: ! 155: SymTab::SymTab(Core* c,int stabfd, SymTab *i, long r) ! 156: { ! 157: trace("%d.SymTab(%d,%d)", this, c, stabfd); VOK; ! 158: _core = c; ! 159: fd = stabfd; ! 160: inherit = i; ! 161: relocation = r; ! 162: _blk = new Block(this, 0, 0, sf("%s.glb_blk", ! 163: stabpath()?stabpath():"")); ! 164: } ! 165: ! 166: void SymTab::opentypes() ! 167: { ! 168: if( !_pad ){ ! 169: _pad = new Pad((PadRcv*) this); ! 170: banner(); ! 171: } ! 172: _pad->makecurrent(); ! 173: } ! 174: ! 175: SymTab::~SymTab() ! 176: { ! 177: void abort(); ! 178: trace( "%d.~SymTab()", this ); VOK; ! 179: if( _pad ) delete _pad; ! 180: if( strings ) delete strings; ! 181: Source *_rootrsib; ! 182: for( ; _root; _root = _rootrsib){ ! 183: _rootrsib = (Source*) _root->rsib; // new malloc ! 184: _root->srctext->userclose(); ! 185: delete _root; ! 186: } ! 187: for( int i = 0; i <= TOSYM; ++i ) ! 188: for( int j = 0; j < HASH; ++j ) ! 189: for( Symbol *s = hashtable[i][j]; s; s = s->hashlink ) ! 190: switch( s->disc() ){ ! 191: case U_UTYPE: delete (UType*)s; break; ! 192: case U_GLB: ! 193: case U_STA: ((Var*)s)->type.free(); ! 194: delete (Var*) s; ! 195: break; ! 196: case U_FUNC: delete (Func*) s; break; ! 197: case U_STMT: delete (Stmt*) s; break; ! 198: default: abort(); ! 199: } ! 200: } ! 201: ! 202: Core *SymTab::core() { OK(0); return _core; } ! 203: Source *SymTab::root() { OK(0); return _root; } ! 204: long SymTab::modtime() { OK(0); return modified(fd); } ! 205: Block *SymTab::blk() { OK(0); return _blk; } ! 206: long SymTab::magic() { OK(0); return _magic; } ! 207: ! 208: Var *SymTab::globregs(Block *b, int r) ! 209: { ! 210: Var *g = 0; ! 211: int i; ! 212: ! 213: trace("%d.globregs(%d,%d)", this, b, r); OK(0); ! 214: for( i = 0; i<r; ++i ){ ! 215: g = new Var(this, b, g, U_REG, sf("$%s",_core->regname(i)) ); ! 216: g->range.lo = i; ! 217: g->type.pcc = LONG; ! 218: if( !b->var ) b->var = g; ! 219: } ! 220: return g; ! 221: } ! 222: ! 223: char *SymTab::dump() ! 224: { ! 225: int i, j; ! 226: Symbol *s; ! 227: ! 228: OK("SymTab::dump"); ! 229: trace( "stabpath()=%s entries=%d", stabpath(), strings ); ! 230: trace( "strings=%d strsize=%d", strings, strsize ); ! 231: for( i = 0; i <= TOSYM; ++i ) ! 232: for( j = 0; j < HASH; ++j ) ! 233: for( s = hashtable[i][j]; s; s = s->hashlink ) ! 234: trace( "%s", s->dump() ); ! 235: return "SymTab::dump"; ! 236: } ! 237: ! 238: void SymTab::read() ! 239: { ! 240: char *error; ! 241: ! 242: trace( "%d.read()", this ); VOK; ! 243: trace( "symtab modified %d", modtime() ); ! 244: _root = 0; ! 245: if( error = gethdr() ) ! 246: _warn = sf( "symbol table header: %s; go on", error ); ! 247: else if( !entries ) ! 248: _warn = "symbol table missing; go on"; ! 249: else if( !(_root = tree()) ) ! 250: _warn = sf( "%s; go on", _warn ? _warn : "symbol table error" ); ! 251: trace( "%s", dump() ); ! 252: } ! 253: ! 254: void SymTab::enter( Symbol *s ) ! 255: { ! 256: int i, h; ! 257: ! 258: trace( "%d.enter(%d) %s %d", this, s, s->dump(), HASHF(s->_text) ); VOK; ! 259: s->hashlink = hashtable[i=s->disc()&TOSYM][h=HASHF(s->_text)]; ! 260: hashtable[i][h] = s; ! 261: } ! 262: ! 263: ! 264: Block *SymTab::fakeblk() /* VAX ap offsets */ ! 265: { ! 266: Block *b; ! 267: int i; ! 268: Var *a = 0; ! 269: ! 270: b = new Block( this, 0, 0, "?().arg_blk" ); ! 271: new Block( this, b, 0, "?().lcl_blk" ); ! 272: for( i = 1; i <= 3; ++i ){ ! 273: a = new Var( this, b, a, U_ARG, sf( "$arg%d", i ) ); ! 274: if( i==1 ) b->var = a; ! 275: a->range.lo = (i+1)*4; ! 276: a->type.pcc = INT; ! 277: } ! 278: return b; ! 279: } ! 280: ! 281: Symbol *SymTab::idtosym(SSet set, register char *id, int lev) ! 282: { ! 283: register int i, h; ! 284: register Symbol *s; ! 285: ! 286: trace("%d.idtosym(%d,%s) %d", this, set.v[0], id?id:"0", HASHF(id)); OK(0); ! 287: ++IdToSymCalls; ! 288: if( !id ) return 0; ! 289: h = HASHF(id); ! 290: for( i = 0; set.v[i]; ++i ){ ! 291: trace( "%s", DiscName(set.v[i]) ); ! 292: for( s = hashtable[set.v[i]&TOSYM][h]; s; s = s->hashlink ){ ! 293: trace( "%s", s->dump() ); ! 294: ++StrCmpCalls; ! 295: if( eqstr(id,s->_text) ) return s; ! 296: } ! 297: } ! 298: return (lev>0 && inherit) ? inherit->idtosym(set,id,lev-1) : 0; ! 299: } ! 300: ! 301: inline Symbol *LookupCache::match(SSet _set, long _loc) ! 302: { ! 303: return !strcmp(_set.v, set.v) && loc == _loc ? sym : 0; ! 304: } ! 305: ! 306: void LookupCache::save(SSet _set, long _loc, Symbol *_sym) ! 307: { ! 308: set = _set; ! 309: loc = _loc; ! 310: sym = _sym; ! 311: } ! 312: ! 313: int LoctosymHit, Loctosym; ! 314: Symbol *SymTab::loctosym(SSet set, register long loc, int lev) ! 315: { ! 316: register h, best_lo = 0, s_lo; ! 317: register Symbol *s, *best = 0; ! 318: register i, setvi; ! 319: Symbol *ibest; ! 320: ! 321: trace( "%d.loctosym(%d,%d)", this, set.v[0], loc ); OK(0); ! 322: ++Loctosym; ! 323: if( s = loctosymcache.match(set, loc) ){ ! 324: ++LoctosymHit; ! 325: return s; ! 326: } ! 327: for( i = 0; setvi = set.v[i]; ++i ){ ! 328: setvi &= TOSYM; ! 329: for( h = 0; h < HASH; ++h ){ ! 330: for( s = hashtable[setvi][h]; s; s = s->hashlink ){ ! 331: s_lo = s->range.lo; ! 332: if( loc < s_lo ! 333: ||( best && best_lo >= s_lo ) ! 334: ||( s->range.hi && loc > s->range.hi ) ) ! 335: continue; ! 336: best = s; ! 337: best_lo = best->range.lo; ! 338: if( loc == best_lo ) goto returnbest; ! 339: } ! 340: } ! 341: } ! 342: if( lev>0 && inherit && (ibest = inherit->loctosym(set,loc,lev-1)) ){ ! 343: if( !best || ibest->range.lo > best->range.lo ){ ! 344: best = ibest; ! 345: goto returnbest; ! 346: } ! 347: } ! 348: returnbest: ! 349: loctosymcache.save(set, loc, best); ! 350: return best; ! 351: } ! 352: ! 353: char *SymTab::symaddr(long a) ! 354: { ! 355: trace( "%d.symaddr(%d)", this, a ); OK("SymTab::symaddr"); ! 356: return Format(F_SYMBOLIC, this).f(a); ! 357: } ! 358: ! 359: Index SymTab::utypecarte(short sorety) ! 360: { ! 361: Menu m; ! 362: UType *u; ! 363: Action a = (Action)&Phrase::applycast; ! 364: char *index(char*,char); ! 365: ! 366: trace( "%d.utypecarte(%d)", this, sorety ); OK(ZIndex); ! 367: if( !castix[sorety].null() ) return castix[sorety]; ! 368: for( u = utype; u; u = (UType *)u->rsib ){ ! 369: if( ::index(u->text(),'$') ) continue; /* $ ? */ ! 370: if( u->type.pcc == sorety ) ! 371: m.sort( sf("%s\240",u->text()), a, (long) &u->type ); ! 372: } ! 373: if( inherit && !inherit->utypecarte(sorety).null() ){ ! 374: Menu s; ! 375: s.first(inherit->utypecarte(sorety)); ! 376: m.last(s.index("inherit")); ! 377: } ! 378: return castix[sorety] = m.index(); ! 379: } ! 380: ! 381: Block *SymTab::gatherfunc(Func*) { IF_LIVE(1) return 0; } ! 382: Var *SymTab::gatherutype(UType*) { IF_LIVE(1) return 0; } ! 383: ! 384: void SymbolStats() ! 385: { ! 386: void WireTap(...); ! 387: ! 388: int fpc = FunctionStubs ? FunctionGathered*100/FunctionStubs : 0; ! 389: int upc = UTypeStubs ? UTypeGathered*100/UTypeStubs : 0; ! 390: static int prevfpc = -1, prevupc = -1; ! 391: if( fpc>prevfpc || upc>prevupc ) ! 392: WireTap("FG=%d FS=%d UG=%d US=%d\n", FunctionGathered, ! 393: FunctionStubs, UTypeGathered, UTypeStubs); ! 394: prevfpc = fpc; ! 395: prevupc = upc; ! 396: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.