|
|
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.