home *** CD-ROM | disk | FTP | other *** search
/ messroms.de / 2007-01-13_www.messroms.de.zip / VZ200 / TOOLS / ZCCSRC.ZIP / link / lksym.c < prev    next >
C/C++ Source or Header  |  2000-03-01  |  4KB  |  263 lines

  1. /* lksym.c */
  2.  
  3. /*
  4.  * (C) Copyright 1989,1990
  5.  * All Rights Reserved
  6.  *
  7.  * Alan R. Baldwin
  8.  * 721 Berkeley St.
  9.  * Kent, Ohio  44240
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <alloc.h>
  15. #include "aslink.h"
  16.  
  17. /*
  18.  * This routine is called early in the
  19.  * game to set up the symbol hashtable.
  20.  */
  21. void
  22. syminit()
  23. {
  24.     struct sym **spp;
  25.  
  26.     spp = &symhash[0];
  27.     while (spp < &symhash[NHASH])
  28.         *spp++ = NULL;
  29. }
  30.  
  31. /*
  32.  * Find/Create a global symbol entry.
  33.  *
  34.  * S xxxxxx Defnnnn
  35.  *   |      |  |
  36.  *   |      |  `-- sp->s_addr
  37.  *   |      `----- sp->s_type
  38.  *   `------------ sp->s_id
  39.  *
  40.  */
  41. struct sym *newsym(void)
  42. {
  43.     int c;
  44.     addr_t i, nglob;
  45.     struct sym *tsp;
  46.     struct sym **s;
  47.     char id[NCPS];
  48.  
  49.     getid(id, -1);
  50.     tsp = lkpsym(id, 1);
  51.     c = getnb();
  52.     get();
  53.     get();
  54.     if (c == 'R')
  55.     {
  56.         tsp->s_type |= S_REF;
  57.         if (eval())
  58.             fprintf(stderr, "Non zero S_REF\n");
  59.     }
  60.     else
  61.     if (c == 'D')
  62.     {
  63.         i = eval();
  64.         if (tsp->s_type & S_DEF && tsp->s_addr != i)
  65.             fprintf(stderr, "Multiple definition of %.8s\n", id);
  66.         tsp->s_type |= S_DEF;
  67.         /*
  68.          * Set value and area extension link.
  69.          */
  70.         tsp->s_addr = i;
  71.         tsp->s_axp = axp;
  72.     }
  73.     else
  74.     {
  75.         fprintf(stderr, "Invalid symbol type %c for %.8s\n", c, id);
  76.         exit(1);
  77.     }
  78.     /*
  79.      * Place pointer in header symbol list
  80.      */
  81.     if (headp == NULL)
  82.     {
  83.         fprintf(stderr, "No header defined\n");
  84.         exit(1);
  85.     }
  86.     nglob = hp->h_nglob;
  87.     s = hp->s_list;
  88.     for (i = 0; i < nglob; ++i)
  89.     {
  90.         if (s[i] == NULL)
  91.         {
  92.             s[i] = tsp;
  93.             return (tsp);
  94.         }
  95.     }
  96.     fprintf(stderr, "Header symbol list overflow\n");
  97.     exit(1);
  98. }
  99.  
  100. /*
  101.  * Lookup the name `id' in the hashtable.
  102.  * If it is not found either return a
  103.  * `NULL' (`f' is false) or a
  104.  * pointer to a newly created hash table
  105.  * entry (`f' is true).
  106.  */
  107. struct sym *lkpsym(char *id, int f)
  108. {
  109.     struct sym *sp;
  110.     int h;
  111.  
  112.     h = hash(id);
  113.     sp = symhash[h];
  114.     while (sp != NULL)
  115.     {
  116.         if (symeq(id, sp->s_id))
  117.             return (sp);
  118.         sp = sp->s_sp;
  119.     }
  120.     if (f == 0)
  121.         return (NULL);
  122.     sp = (struct sym *)new (sizeof (struct sym));
  123.  
  124.     sp->s_sp = symhash[h];
  125.     symhash[h] = sp;
  126.     strncpy(sp->s_id, id, NCPS);
  127.     return (sp);
  128. }
  129.  
  130. /*
  131.  * Get value of relocated symbol
  132.  */
  133. addr_t symval(struct sym *tsp)
  134. {
  135.     addr_t val;
  136.  
  137.     val = tsp->s_addr;
  138.     if (tsp->s_axp)
  139.     {
  140.         val += tsp->s_axp->a_addr;
  141.     }
  142.     return (val);
  143. }
  144.  
  145. /*
  146.  * Check for undefined symbols
  147.  */
  148. void symdef(FILE *fp)
  149. {
  150.     struct sym *sp;
  151.     int i;
  152.  
  153.     for (i = 0; i < NHASH; ++i)
  154.     {
  155.         sp = symhash[i];
  156.         while (sp)
  157.         {
  158.             if (sp->s_axp == NULL)
  159.                 sp->s_axp = areap->a_axp;
  160.             if ((sp->s_type & S_DEF) == 0)
  161.                 symmod(fp, sp);
  162.             sp = sp->s_sp;
  163.         }
  164.     }
  165. }
  166.  
  167. void symmod(FILE *fp, struct sym *tsp)
  168. {
  169.     int i;
  170.     struct sym **p;
  171.  
  172.     if ((hp = headp) != NULL)
  173.     {
  174.         while (hp)
  175.         {
  176.             p = hp->s_list;
  177.             for (i = 0; i < hp->h_nglob; ++i)
  178.             {
  179.                 if (p[i] == tsp)
  180.                 {
  181.                     fprintf(fp, "\n?ASlink-W-Undefined Global %8.8s ", tsp->s_id);
  182.                     fprintf(fp, "referenced by module %8.8s\n", hp->m_id);
  183.                 }
  184.             }
  185.             hp = hp->h_hp;
  186.         }
  187.     }
  188. }
  189.  
  190. /*
  191.  * Compare two symbol names.
  192.  */
  193. int symeq(char *p1, char *p2)
  194. {
  195.     int n;
  196.  
  197.     n = NCPS;
  198.     do
  199.     {
  200.  
  201. #if    CASE_SENSITIVE
  202.         if (*p1++ != *p2++)
  203.             return (0);
  204. #else
  205.         if (ccase[*p1++] != ccase[*p2++])
  206.             return (0);
  207. #endif
  208.  
  209.     }
  210.     while (--n);
  211.     return (1);
  212. }
  213.  
  214. /*
  215.  * Given a pointer to a symbol name
  216.  * compute and return the hash table
  217.  * bucket.
  218.  * The `sum of all the characters mod
  219.  * table size' algorithm is perhaps
  220.  * not the best.
  221.  */
  222. int hash(char *p)
  223. {
  224.     int h, n;
  225.  
  226.     h = 0;
  227.     n = NCPS;
  228.     do
  229.     {
  230.  
  231. #if    CASE_SENSITIVE
  232.         h += *p++;
  233. #else
  234.         h += ccase[*p++];
  235. #endif
  236.  
  237.     }
  238.     while (--n);
  239.     return (h & HMASK);
  240. }
  241.  
  242. /*
  243.  * Allocate and clear a block of space.
  244.  * Leave if there is no space left
  245.  * at all.
  246.  */
  247. void *new (unsigned int n)
  248. {
  249.     char *p, *q;
  250.     unsigned int i;
  251.  
  252.     if ((p = (char *)malloc(n)) == NULL)
  253.     {
  254.         fprintf(stderr, "Out of space!\n");
  255.         exit(1);
  256.     }
  257.     for (i = 0, q = p; i < n; i++)
  258.     {
  259.         *q++ = 0;
  260.     }
  261.     return (p);
  262. }
  263.