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