home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 303_01 / alloc.c < prev    next >
Text File  |  1990-05-15  |  7KB  |  345 lines

  1. /*
  2.  *    SCCS:    %W%    %G%    %U%
  3.  *    Allocate space etc.
  4.  *
  5.  *EMACS_MODES:c
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <a.out.h>
  10. #include <setjmp.h>
  11. #ifdef    COFF
  12. #include <ldfcn.h>
  13. #endif    /*  COFF  */
  14. #include "unc.h"
  15.  
  16. #define    STINC    10
  17.  
  18. char    *malloc(), *realloc();
  19. char    *strncpy();
  20. void    gette(), getde(), setde(), putte(), putde();
  21. void    unimpl();
  22. long    gettw();
  23.  
  24. ef_fids    mainfile;
  25.  
  26. /*
  27.  *    Oops! out of memory.....
  28.  */
  29.  
  30. void    nomem()
  31. {
  32.     (void) fprintf(stderr, "Sorry - run out of memory\n");
  33.     exit(255);
  34. }
  35.  
  36. /*
  37.  *    Look up hash value of symbol.
  38.  */
  39.  
  40. unsigned  shash(str)
  41. register  char    *str;
  42. {
  43.     register  unsigned  result = 0;
  44.     register  int    cnt = 0;
  45.     
  46.     while  (*str  &&  cnt < MAXCHARS)  {
  47.         result += *str++;
  48.         cnt++;
  49.     }
  50.     return  result % HASHMOD;
  51. }
  52.  
  53. /*
  54.  *    Look up hash value of symbol, possibly allocating a new symbol.
  55.  */
  56.  
  57. symbol    lookup(str)
  58. char    *str;
  59. {
  60.     register  symbol  res, *pp;
  61.     register  int    len;
  62.     
  63.     pp = &symbhash[shash(str)];
  64.     res = *pp;
  65.     while  (res != NULL)  {
  66.         if  (strncmp(res->s_name, str, MAXCHARS) == 0)
  67.             return    res;
  68.         pp = &res->s_next;
  69.         res = *pp;
  70.     }
  71.     for  (len = 0;  len < MAXCHARS;  len++)
  72.         if  (str[len] == '\0')
  73.             break;
  74.     len++;
  75.     res = (symbol) malloc(sizeof(struct symstr) + len);
  76.     if  (res == NULL)
  77.         nomem();
  78.     *pp = res;
  79.     res->s_next = NULL;
  80.     (void) strncpy(res->s_name, str, len);
  81.     res->s_name[len] = '\0';        /*  Null-terminate  */
  82.     res->s_newsym = 1;
  83.     res->s_glob = 0;
  84.     res->s_invent = 0;
  85.     res->s_link = NULL;
  86.     res->s_used = 0;
  87.     res->s_defs = 0;
  88.     res->s_lsymb = 0;
  89.     return  res;
  90. }
  91.  
  92. /*
  93.  *    Invent a symbol, making sure that we don't know it.
  94.  */
  95.  
  96. symbol    inventsymb(prefix)
  97. char    *prefix;
  98. {
  99.     static    int  nsymb = 0;
  100.     char    schars[10];
  101.     register  symbol  res;
  102.     
  103.     do    (void) sprintf(schars, "%s%d", prefix, ++nsymb);
  104.     while  (!(res = lookup(schars))->s_newsym);
  105.     
  106.     res->s_newsym = 0;
  107.     res->s_invent = 1;
  108.     return    res;
  109. }
  110.      
  111. /*
  112.  *    Reallocate symbol table.
  113.  */
  114.  
  115. void    reallst(outf)
  116. register  ef_fid  outf;
  117. {
  118.     outf->ef_stmax += STINC;
  119.     if  (outf->ef_stvec == NULL)
  120.         outf->ef_stvec = (symbol *) malloc(outf->ef_stmax * sizeof(symbol));
  121.     else
  122.         outf->ef_stvec = (symbol *) realloc(outf->ef_stvec,
  123.                     outf->ef_stmax * sizeof(symbol));
  124.     if  (outf->ef_stvec == NULL)
  125.         nomem();
  126. }
  127.  
  128. /*
  129.  *    Search through existing symbol table for symbol with given
  130.  *    value.  Invent a new one if needed.
  131.  */
  132.  
  133. symbol    getnsymb(fid, seg, pos)
  134. register  ef_fid  fid;
  135. unsigned  seg;
  136. long    pos;
  137. {
  138.     register  int    i;
  139.     register  symbol  res;
  140.     
  141.     /***********  MACHINE DEPENDENT  ******************************
  142.      *    Convert relocation segment type (argument) to symbol type
  143.      *    (as remembered in symbol table).  Don't ask me why they
  144.      *    have to be different.....
  145.      */
  146.     
  147. #ifndef    COFF
  148.     seg += TEXT - RTEXT;
  149.     
  150. #endif    /*  !COFF  */
  151.     /*
  152.      *    See if the reference is to an external symbol.
  153.      *    If so, use that.
  154.      */
  155.     
  156.     for  (i = 0;  i < fid->ef_stcnt;  i++)  {
  157.         res = fid->ef_stvec[i];
  158.         if  (res->s_type == seg  &&  res->s_value == pos)
  159.             return    res;
  160.     }
  161.     
  162.     /*
  163.      *    Invent a symbol and use that.
  164.      */
  165.     
  166.     res = inventsymb("RS");
  167.     if  (fid->ef_stcnt >= fid->ef_stmax)
  168.         reallst(fid);
  169.     fid->ef_stvec[fid->ef_stcnt++] = res;
  170.     res->s_type = seg;
  171.     res->s_value = pos;
  172. #ifdef    COFF
  173.     if  (seg == S_TEXT)  {
  174. #else    /*  !COFF  */
  175.     if  (seg == TEXT)  {
  176. #endif    /*  !COFF  */
  177.         t_entry    tent;
  178.         gette(fid, pos, &tent);
  179.         tent.t_bdest = 1;
  180.         tent.t_lab = res;
  181.         putte(fid, pos, &tent);
  182.     }
  183. #ifdef    COFF
  184.     else  if  (seg == S_DATA  ||  seg == S_BSS)  {
  185. #else    /*  !COFF  */
  186.     else  if  (seg == DATA  ||  seg == BSS)  {
  187. #endif    /*  !COFF  */
  188.         d_entry dent;
  189.         getde(fid, pos, &dent);
  190.         dent.d_lab = res;
  191.         putde(fid, pos, &dent);
  192.     }
  193.  
  194.     return    res;
  195. }
  196.  
  197. /*
  198.  *    Assuming address given is in text segment, find its label, or invent
  199.  *    one.  Also set where refered from.
  200.  */
  201.  
  202. symbol    textlab(loc, refpos)
  203. long    loc, refpos;
  204. {
  205.     t_entry    tent;
  206.  
  207.     gette(&mainfile, loc, &tent);
  208.     if  (tent.t_type == T_CONT)
  209.         return    NULL;
  210.     if  (tent.t_lab == NULL)  {
  211.         tent.t_lab = inventsymb("TS");
  212. #ifdef    COFF
  213.         tent.t_lab->s_type = S_TEXT;
  214. #else    /*  !COFF  */
  215.         tent.t_lab->s_type = TEXT;
  216. #endif    /*  !COFF  */
  217.         tent.t_lab->s_value = loc;
  218.         tent.t_bdest = 1;
  219.         putte(&mainfile, loc, &tent);
  220.     }
  221.     else
  222.         tent.t_lab->s_used++;
  223.     if  (tent.t_refhi < refpos)  {
  224.         tent.t_refhi = refpos;
  225.         putte(&mainfile, loc, &tent);
  226.     }
  227.     if  (tent.t_reflo > refpos)  {
  228.         tent.t_reflo = refpos;
  229.         putte(&mainfile, loc, &tent);
  230.     }
  231.     return    tent.t_lab;
  232. }
  233.  
  234. /*
  235.  *    Note references to data.
  236.  */
  237.  
  238. void    mkdref(tpos, size)
  239. long    tpos;
  240. unsigned  size;
  241. {
  242.     t_entry    tent;
  243.     d_entry    dent;
  244.     register  symbol  ds;
  245.     int    dchng = 0;
  246.     int    wsize;
  247.     long    dpos;
  248.     
  249.     gette(&mainfile, tpos, &tent);
  250.     if  (tent.t_relsymb != NULL)
  251.         return;
  252.         
  253.     dpos = gettw(&mainfile, tpos, R_LONG);
  254.     if  (dpos < mainfile.ef_dbase  ||  dpos > mainfile.ef_end)
  255.         return;
  256.     
  257.     switch  (size)  {
  258.     default:
  259.         wsize = D_BYTE;
  260.         break;
  261.     case  2:
  262.         wsize = D_WORD;
  263.         break;
  264.     case  4:
  265.         wsize = D_LONG;
  266.         break;
  267.     }
  268.     
  269.     getde(&mainfile, dpos, &dent);
  270.     if  ((ds = dent.d_lab) == NULL)  {
  271.         if  (dpos >= mainfile.ef_bbase)  {
  272.             ds = inventsymb("BS");
  273. #ifdef    COFF
  274.             ds->s_type = S_BSS;
  275. #else    /*  !COFF  */
  276.             ds->s_type = BSS;
  277. #endif    /*  !COFF  */
  278.         }
  279.         else  {
  280.             ds = inventsymb("DS");
  281. #ifdef    COFF
  282.             ds->s_type = S_DATA;
  283. #else    /*  !COFF  */
  284.             ds->s_type = DATA;
  285. #endif    /*  !COFF  */
  286.         }
  287.         ds->s_value = dpos;
  288.         dent.d_lab = ds;
  289.         dchng++;
  290.     }
  291.     else
  292.         ds->s_used++;
  293.  
  294.     if  (dent.d_type != D_BYTE)  {
  295.         if  (dent.d_type != wsize)  {
  296.             if  (dent.d_type == D_ADDR)  {
  297.                 if  (wsize != D_LONG)
  298.                     unimpl("Addr word usage");
  299.             }
  300.             else  if  (dent.d_type > wsize)  {
  301.                 dchng++;
  302.                 dent.d_type = wsize;
  303.                 dent.d_lng = size;
  304.             }
  305.         }
  306.     }
  307.     else  {
  308.         dent.d_type = wsize;
  309.         dent.d_lng = size;
  310.         dchng++;
  311.     }
  312.     if  (dchng)  {
  313.         putde(&mainfile, dpos, &dent);
  314.         for  (dchng = 1;  dchng < size; dchng++)
  315.             setde(&mainfile, dpos+dchng, D_CONT, 1);
  316.     }
  317.         
  318.     tent.t_relsymb = ds;
  319.     putte(&mainfile, tpos, &tent);
  320. }
  321.  
  322. /*
  323.  *    Add item to common or abs list.
  324.  */
  325.  
  326. #define    COMINC    10
  327.  
  328. void    addit(cp, symb)
  329. register  struct  commit  *cp;
  330. symbol    symb;
  331. {
  332.     if  (cp->c_int >= cp->c_max)  {
  333.         cp->c_max += COMINC;
  334.         if  (cp->c_symb == NULL)
  335.             cp->c_symb = (symbol *) malloc(COMINC*sizeof(symbol));
  336.         else
  337.             cp->c_symb = (symbol *)
  338.                     realloc(cp->c_symb,
  339.                         cp->c_max * sizeof(symbol));
  340.         if  (cp->c_symb == NULL)
  341.             nomem();
  342.     }
  343.     cp->c_symb[cp->c_int++] = symb;
  344. }
  345.