|
|
1.1 root 1: /*
2: * Symbol table functions.
3: */
4: #include <asm.h>
5: #include <symtab.h>
6: #include <y_tab.h>
7:
8: #define SHASH ((unsigned short)1021) /* symbol table hash */
9: sym **symhash; /* macros equs and symbols */
10: static char *lastSym; /* last symbol defined */
11:
12: /*
13: * This routine is called early in the
14: * game to set up the hashtable.
15: */
16: void
17: symInit()
18: {
19: register psym *sp;
20: register unsigned short ht;
21:
22: symhash = (sym **)alloc(SHASH * sizeof(sp));
23:
24: /* init symbol table */
25: for(sp = symtab; sp < symtab + SYMCOUNT; sp++) {
26: if (rswitch && ('%' == sp->name[0]) && sp->name[1])
27: sp->name++;
28: sp->next = symhash[ht = hash(sp->name) % SHASH];
29: symhash[ht] = (sym *)sp;
30: }
31:
32: lastSym = ""; /* last symbol defined is null */
33: }
34:
35: /*
36: * Free macro space.
37: */
38: freeMac(mp)
39: register macro *mp;
40: {
41: freeList((parm *)mp->first); /* free lines */
42: freeList(mp->names); /* free parms */
43: free((char *)mp); /* free macro */
44: }
45:
46: /*
47: * Returns a 1 if this symbol should not be output
48: * to the symbol table.
49: */
50: static
51: notSym(sp)
52: register sym *sp;
53: {
54: /* don't out put symbols given numbers already */
55: if (sp->num)
56: return (1);
57:
58: /* don't output unused .globls */
59: if ((sp->flag & S_EXREF) && !(sp->flag & S_USED))
60: return (1);
61:
62: if (!(sp->flag & (S_EXREF|S_EXDEF))) {
63: register char *p;
64:
65: /* don't output non global symbols if -x option */
66: if (xswitch)
67: return (1);
68:
69: p = SYMNAME(sp);
70:
71: /* don't output symbols starting .L is -X option */
72: if (Xswitch && (p[0] == '.') && (p[1] == 'L'))
73: return (1);
74:
75: /* don't output local symbols */
76: if (NULL != strchr(p, ';'))
77: return (1);
78: }
79:
80: /* don't output dot symbol */
81: if (&dot == (psym *)sp)
82: return (1);
83:
84: return (0);
85: }
86:
87: /*
88: * Give numbers to all identifier symbols.
89: * Mark undefined symbols as exref if -g.
90: * Delete symbols defined by macro, equs and equ.
91: * Called at the end of pass 0 and 1.
92: */
93: unsigned short
94: symGlob(number)
95: {
96: register sym *sp, **psp;
97: register unsigned short i;
98:
99: for(i = 0; i < SHASH; i++) {
100: for(psp = symhash + i; NULL != (sp = *psp); ) {
101: switch(sp->type) {
102: case MACTYPE: /* delete macro */
103: case MACSTR: /* delete define */
104: *psp = sp->next; /* rechain list */
105: freeMac((macro *)sp);
106: continue;
107:
108: case NUMBER: /* delete equ */
109: if ((2 == pass) && (sp->flag & S_EXDEF))
110: sp->num = number++;
111: sp->type = IDENTIFIER;
112: sp->flag = S_UNDEF;
113: break;
114:
115: case IDENTIFIER:
116: if((sp->flag & S_UNDEF) && gswitch)
117: sp->flag = (S_EXREF | S_USED);
118:
119: if((2 == pass) && !notSym(sp))
120: sp->num = number++;
121: }
122: psp = &(sp->next); /* follow list */
123: }
124: }
125: lastSym = "";
126: return(number);
127: }
128:
129: /*
130: * Dump symbol data
131: */
132: void
133: symDump(output, limit)
134: int (*output)();
135: long limit;
136: {
137: register sym *sp;
138: register i;
139:
140: for(i = 0; i < SHASH; i++)
141: for(sp = symhash[i]; NULL != sp; sp = sp->next) {
142: if(sp->num > limit) {
143: switch(sp->type) {
144: case NUMBER:
145: case IDENTIFIER:
146: (*output)(sp);
147: }
148: }
149: }
150: }
151:
152: /*
153: * This is called when debug records are created. It repoints
154: * the symbol number to one of the debug records. symDump then
155: * uses this information to avoid dumping the symbol twice.
156: * This means debug data can seriously screw up an output file
157: * if it is wrong.
158: */
159: symReNumber(id, number)
160: char *id;
161: int number;
162: {
163: short i;
164: register sym *sp;
165:
166: for(sp = symhash[i = hash(id) % SHASH];
167: sp != NULL;
168: sp = sp->next) {
169: if(!strcmp(id, SYMNAME(sp))) {
170: sp->num = number;
171: break;
172: }
173: }
174: }
175:
176: /*
177: * Undefined symbol message.
178: */
179: static void
180: unDefMsg(id)
181: char *id;
182: {
183: char *pt;
184:
185: if(NULL != (pt = strchr(id, ';'))) {
186: *pt = '\0';
187: yyerror("Undefined symbol '?%s'", id);
188: /* NODOC */
189: *pt = ';';
190: }
191: else
192: yyerror("Undefined symbol '%s'", id);
193: /* A symbol was used without defining it or using
194: * a \fB-g\fR option.
195: * You must define local symbols. */
196: }
197:
198: /*
199: * Redefined symbol message.
200: */
201: static void
202: redef(id)
203: char *id;
204: {
205: yyerror("Redefinition of '%s'", id);
206: /* An assembler internal symbol is being redefined. */
207: }
208:
209: /*
210: * Duplicate symbol message.
211: */
212: static void
213: dupsym(id)
214: register char *id;
215: {
216: register char *pt;
217:
218: if(NULL != (pt = strchr(id, ';'))) {
219: *pt = '\0';
220: yyerror("Duplicate symbol '?%s'", id);
221: /* NODOC */
222: *pt = ';';
223: }
224: else
225: yyerror("Duplicate symbol '%s'", id);
226: /* \fIsymbol\fR is defined on two different lines. */
227: }
228:
229: /*
230: * Lookup the name `id' in a hashtable.
231: * If it is not found build it.
232: */
233: sym *
234: symLookUp(id, flag, loc, sg)
235: long loc;
236: char *id;
237: {
238: register sym *sp;
239: char *locSym;
240: short i;
241:
242: if('?' == id[0] && id[1]) { /* local symbol */
243: locSym = galloc((unsigned)(strlen(id) + strlen(lastSym) + 1));
244: sprintf(locSym, "%s;%s", id + 1, lastSym);
245: id = locSym;
246: }
247: else
248: locSym = NULL;
249:
250: for(sp = symhash[i = hash(id) % SHASH];
251: sp != NULL;
252: sp = sp->next) {
253: if((sp->type > MACSCAN) && !strcmp(id, SYMNAME(sp))) {
254: if(2 == pass) {
255: switch(flag) {
256: case S_UNDEF: /* we are looking for it */
257: if((S_UNDEF & sp->flag) &&
258: (DEFINED != lastToken) &&
259: (S_GLOBL != kind))
260: unDefMsg(id);
261: if (sp->flag & S_ASYM)
262: sp->flag |= S_USED;
263: return(sp);
264:
265: case S_LOCAL: /* being defined here */
266: if(!(sp->flag & S_ASYM))
267: redef(id);
268:
269: else if(sp->flag & S_EXREF) {
270: sp->flag &= ~S_EXREF;
271: sp->flag |= S_EXDEF|S_LOCAL;
272: }
273: else if(statement != sp->statement)
274: dupsym(id);
275: else if((sp->loc != loc) ||
276: (sp->sg != sg))
277: yyerror("Phase error '%s'",
278: id);
279: /* A symbol is defined one way in one phase of the assembly
280: * and another way in the next phase. */
281: break;
282:
283: case S_XSYM: /* a number */
284: if(!(sp->flag & S_ASYM)) {
285: redef(id);
286: return(sp);
287: }
288: if (sp->flag & S_LOCAL)
289: dupsym(id);
290: if (sp->flag & S_EXREF) {
291: sp->flag &= ~S_EXREF;
292: sp->flag |= S_EXDEF;
293: }
294: sp->flag &= ~(S_UNDEF|S_LOCAL);
295: sp->flag |= S_XSYM;
296: sp->type = NUMBER;
297: sp->loc = loc;
298: sp->sg = -1; /* absolute */
299: return(sp);
300: }
301: break;
302: }
303: else { /* pass 0 and 1 */
304: switch(flag) {
305: case S_UNDEF: /* looking for it */
306: if (sp->flag & S_ASYM)
307: sp->flag |= S_USED;
308: return(sp);
309:
310: case S_LOCAL: /* being defined here */
311: if(!(sp->flag & S_ASYM))
312: return(sp);
313:
314: sp->statement = statement;
315:
316: if(sp->flag & S_EXREF) {
317: sp->flag &= ~S_EXREF;
318: sp->flag |= S_EXDEF|S_LOCAL;
319: }
320: else {
321: sp->flag &= ~S_UNDEF;
322: sp->flag |= flag;
323: }
324: break;
325:
326: case S_XSYM: /* a number */
327: if(!(sp->flag & S_ASYM))
328: return(sp);
329: if (sp->flag & S_EXREF) {
330: sp->flag &= ~S_EXREF;
331: sp->flag |= S_EXDEF;
332: }
333: sp->flag &= ~(S_UNDEF|S_LOCAL);
334: sp->flag |= S_XSYM;
335: sp->type = NUMBER;
336: sp->loc = loc;
337: sp->sg = -1; /* absolute */
338: return(sp);
339: }
340: break;
341: }
342: }
343: }
344:
345: if(NULL == sp) {
346: if (DEFINED == lastToken) {
347: static psym sy = {
348: NULL, IDENTIFIER, 0, 0, 0, S_UNDEF,
349: NULL, 0, 0, NULL
350: };
351:
352: return (&sy);
353: }
354: sp = (sym *) scpy(id, offset(sym, name));
355: sp->next = symhash[i];
356: sp->ref = symhash[i] = sp;
357: sp->flag = flag;
358: }
359: sp->type = IDENTIFIER;
360: switch(flag) {
361: case S_UNDEF:
362: if (S_GLOBL != kind)
363: sp->flag |= S_USED;
364: break;
365: case S_XSYM:
366: sp->type = NUMBER;
367: sp->loc = loc;
368: sp->sg = -1; /* absolute */
369: break;
370: case S_LOCAL:
371: sp->loc = loc;
372: sp->sg = sg;
373: sp->statement = statement;
374: if(NULL == locSym)
375: lastSym = sp->name;
376: }
377: return(sp);
378: }
379:
380: /*
381: * Lookup a name in opcodes.
382: * return it's index or -1.
383: */
384: short
385: opLookUp(id)
386: char *id;
387: {
388: register nhash *op;
389: short i, l;
390:
391: for (l = strlen(id), i = hash(id) % OPCOUNT;;) {
392: if ((l == (op = hashCodes + i)->nlen) &&
393: !memcmp(id, (charLump + op->nameIx), l)) {
394: choices = op->count;
395: return(op->prefIx);
396: }
397: if (-1 == (i = op->next))
398: return (-1);
399: }
400: }
401:
402: /*
403: * Remove an entry from the opcode table.
404: */
405: void
406: opDelete(id)
407: char *id;
408: {
409: register nhash *op;
410: short i, l;
411:
412: l = strlen(id);
413: for(i = hash(id) % OPCOUNT; -1 != i; i = op->next) {
414: if((l == (op = hashCodes + i)->nlen) &&
415: !memcmp(id, (charLump + op->nameIx), l)) {
416: op->nlen = 0;
417: return;
418: }
419: }
420: return;
421: }
422:
423: /*
424: * Look up macros and equs symbols. Shares table with symbols.
425: */
426: macro *
427: macLookUp(id, type)
428: char *id;
429: {
430: register macro *mp;
431:
432: for(mp = (macro *)symhash[hash(id) % SHASH];
433: mp != NULL;
434: mp = mp->next)
435: if((mp->type == type) && !strcmp(id, mp->name))
436: return(mp);
437: return(NULL);
438: }
439:
440: /*
441: * Delete a macro or equs.
442: */
443: macDelete(s, t)
444: char *s;
445: short t;
446: {
447: register macro *mp, **pmp;
448: short ht;
449:
450: for(pmp = (macro **)(symhash + (ht = hash(s) % SHASH));
451: NULL != (mp = *pmp);
452: pmp = &(mp->next)) {
453: if((mp->type == t) && !strcmp(s, mp->name)) {
454: *pmp = mp->next; /* unChain */
455: freeMac(mp);
456: break;
457: }
458: }
459: return(ht);
460: }
461:
462: /*
463: * Define macro or equs symbol.
464: * Shares symbol table with other symbols.
465: */
466: void
467: defMac(s, p, t)
468: char *s;
469: parm *p;
470: short t;
471: {
472: register macro *tmp;
473: short ht;
474:
475: ht = macDelete(s, t); /* remove old form */
476: tmp = (macro *)scpy(s, offset(macro, name));
477:
478: tmp->names = p; /* parm names */
479: umList(p);
480:
481: tmp->next = (macro *)symhash[ht];
482: symhash[ht] = (sym *)tmp;
483: if(MACTYPE == (tmp->type = t)) {
484: newLevel(INMACDEF);
485: inMacDef = tmp;
486: }
487: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.