home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / 68kdisassem / part1 / alloc.c next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  6.2 KB  |  338 lines

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