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