home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 332.lha / DAsm_v2.12 / src / symbols.c < prev    next >
C/C++ Source or Header  |  1989-12-27  |  4KB  |  212 lines

  1.  
  2. /*
  3.  *  SYMBOLS.C
  4.  *
  5.  *  (c)Copyright 1988, Matthew Dillon, All Rights Reserved.
  6.  */
  7.  
  8. #include "asm.h"
  9.  
  10. uword hash1 ARGS((ubyte *, short));
  11.  
  12. static SYMBOL org;
  13. static SYMBOL special;
  14. static SYMBOL specchk;
  15.  
  16. void
  17. setspecial(value, flags)
  18. int value, flags;
  19. {
  20.     special.value = value;
  21.     special.flags = flags;
  22. }
  23.  
  24. SYMBOL *
  25. findsymbol(str, len)
  26. ubyte *str;
  27. int len;
  28. {
  29.     register uword h1;
  30.     register SYMBOL *sym;
  31.     ubyte buf[128];
  32.     static SYMBOL org;
  33.  
  34.     if (str[0] == '.') {
  35.     if (len == 1) {
  36.         if (Csegment->flags & SF_RORG) {
  37.         org.flags = Csegment->rflags & SYM_UNKNOWN;
  38.         org.value = Csegment->rorg;
  39.         } else {
  40.         org.flags = Csegment->flags & SYM_UNKNOWN;
  41.         org.value = Csegment->org;
  42.         }
  43.         return(&org);
  44.     }
  45.     if (len == 2 && str[1] == '.')
  46.         return(&special);
  47.     if (len == 3 && str[1] == '.' && str[2] == '.') {
  48.         specchk.flags = 0;
  49.         specchk.value = CheckSum;
  50.         return(&specchk);
  51.     }
  52.     {
  53.         register INCFILE *inc;
  54.         BMov(str+1, buf, --len);
  55.         sprintf(buf + len, ".%ld", Localindex);
  56.         len += strlen(buf+len);
  57.         for (inc = Incfile->next; inc; inc = inc->next) {
  58.         sprintf(buf+len,".%ld", inc->lineno);
  59.         len += strlen(buf+len);
  60.         }
  61.         str = buf;
  62.     }
  63.     }
  64.     h1 = hash1(str, (short)len);
  65.     for (sym = SHash[h1]; sym; sym = sym->next) {
  66.     if (sym->namelen == len && BCmp(sym->name, str, len) == 0)
  67.         break;
  68.     }
  69.     return(sym);
  70. }
  71.  
  72. SYMBOL *
  73. createsymbol(str, len)
  74. ubyte *str;
  75. int len;
  76. {
  77.     register SYMBOL *sym;
  78.     register uword h1;
  79.     ubyte buf[128];
  80.  
  81.     if (str[0] == '.') {
  82.     register INCFILE *inc;
  83.     BMov(str+1, buf, --len);
  84.     sprintf(buf + len, ".%ld", Localindex);
  85.     len += strlen(buf+len);
  86.     for (inc = Incfile->next; inc; inc = inc->next) {
  87.         sprintf(buf+len,".%ld", inc->lineno);
  88.         len += strlen(buf+len);
  89.     }
  90.     str = buf;
  91.     }
  92.     sym = (SYMBOL *)allocsymbol();
  93.     sym->name = permalloc(len+1);
  94.     BMov(str, sym->name, len);        /*  permalloc zero's the array for us */
  95.     sym->namelen = len;
  96.     h1 = hash1(str, (short)len);
  97.     sym->next = SHash[h1];
  98.     sym->flags= SYM_UNKNOWN;
  99.     SHash[h1] = sym;
  100.     return(sym);
  101. }
  102.  
  103. static uword
  104. hash1(str, len)
  105. register ubyte *str;
  106. register short len;
  107. {
  108.     register uword result = 0;
  109.  
  110.     while (len--)
  111.     result = (result << 2) ^ *str++;
  112.     return((uword)(result & SHASHAND));
  113. }
  114.  
  115. /*
  116.  *  Label Support Routines
  117.  */
  118.  
  119. void
  120. programlabel()
  121. {
  122.     register uword len;
  123.     register SYMBOL *sym;
  124.     register SEGMENT *cseg = Csegment;
  125.     register ubyte *str;
  126.     ubyte   rorg = cseg->flags & SF_RORG;
  127.     ubyte   cflags = (rorg) ? cseg->rflags : cseg->flags;
  128.     ulong   pc = (rorg) ? cseg->rorg : cseg->org;
  129.  
  130.     Plab = cseg->org;
  131.     Pflags = cseg->flags;
  132.     str = Av[0];
  133.     if (*str == 0)
  134.     return;
  135.     len = strlen(str);
  136.     if (str[len-1] == ':')
  137.     --len;
  138.  
  139.     /*
  140.      *    Redo:    unknown and referenced
  141.      *        referenced and origin not known
  142.      *        known and phase error    (origin known)
  143.      */
  144.  
  145.     if (sym = findsymbol(str, len)) {
  146.     if ((sym->flags & (SYM_UNKNOWN|SYM_REF)) == (SYM_UNKNOWN|SYM_REF)) {
  147.         ++Redo;
  148.         Redo_why |= 1 << 13;
  149.         if (Xdebug)
  150.         printf("redo 13: '%s' %04x %04x\n", sym->name, sym->flags, cflags);
  151.     } else
  152.     if ((cflags & SYM_UNKNOWN) && (sym->flags & SYM_REF)) {
  153.         ++Redo;
  154.         Redo_why |= 1 << 13;
  155.     } else
  156.     if (!(cflags & SYM_UNKNOWN) && !(sym->flags & SYM_UNKNOWN)) {
  157.         if (pc != sym->value) {
  158.         printf("mismatch %10s %s  pc: %s\n", sym->name, sftos(sym->value, sym->flags), sftos(pc, cflags & 7));
  159.         asmerr(17,0);
  160.         ++Redo;
  161.         Redo_why |= 1 << 14;
  162.         }
  163.     }
  164.     } else {
  165.     sym = createsymbol(str, len);
  166.     }
  167.     sym->value = pc;
  168.     sym->flags = (sym->flags & ~SYM_UNKNOWN) | (cflags & SYM_UNKNOWN);
  169. }
  170.  
  171. SYMBOL *SymAlloc;
  172.  
  173. SYMBOL *
  174. allocsymbol()
  175. {
  176.     SYMBOL *sym;
  177.  
  178.     if (SymAlloc) {
  179.     sym = SymAlloc;
  180.     SymAlloc = SymAlloc->next;
  181.     BZero(sym, sizeof(SYMBOL));
  182.     } else {
  183.     sym = (SYMBOL *)permalloc(sizeof(SYMBOL));
  184.     }
  185.     return(sym);
  186. }
  187.  
  188. void
  189. freesymbol(sym)
  190. SYMBOL *sym;
  191. {
  192.     sym->next = SymAlloc;
  193.     SymAlloc = sym;
  194. }
  195.  
  196. void
  197. freesymbollist(sym)
  198. SYMBOL *sym;
  199. {
  200.     register SYMBOL *next;
  201.  
  202.     while (sym) {
  203.     next = sym->next;
  204.     sym->next = SymAlloc;
  205.     if (sym->flags & SYM_STRING)
  206.         free(sym->string);
  207.     SymAlloc = sym;
  208.     sym = next;
  209.     }
  210. }
  211.  
  212.