Annotation of researchv9/jtools/src/pi/symtab.c, revision 1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.