home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / nasm20b / nasm_src / link.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  13KB  |  525 lines

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1991 by Natuerlich!                    */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. #define LINKER 1
  7. #include "defines.h"
  8. #include "nasm.h"
  9. #include "debug.h"
  10. #include "labels.h"
  11. #include "object.h"
  12. #include "seg.h"
  13. #include "imm.h"
  14. #include OSBIND
  15. #include NMALLOC_H
  16. #include "process.h"
  17. #include "exprfast.h"
  18.  
  19. #include "ldebug.h"
  20.  
  21.  
  22. #if ! VERSION
  23. extern char       x1[], x2[], x3[], x4[], x5[];
  24. #endif
  25.  
  26. extern byte huge        *__program, huge *__p, huge *ptohead;
  27. extern byte             __c;
  28. extern word             __pc, __x;
  29. extern lword            __lx;
  30. extern imm huge         *hip, huge *cip;
  31. extern seg huge         *h_seg, huge *sp;
  32. extern int              relocatable,
  33.                         bootable,
  34.                         pageflag;
  35. extern word             alignment,
  36.                         origin;
  37.  
  38. extern byte       huge  *pb;
  39. extern e_dropped  huge  *pe;
  40. extern s_dropped  huge  *ps;
  41. extern linksymbol huge  *py;
  42. extern i_dropped  huge  *pi;
  43. extern r_dropped  huge  *pr;
  44. extern f_dropped  huge  *pf;
  45. extern lword      bytes, sbytes, ibytes, rbytes, ebytes, ybytes, fbytes;
  46. extern word       endpc, diff;
  47.  
  48. ref               huge  *rhead;
  49.  
  50. seg               huge  **pas;
  51. imm               huge  **pai;
  52. expr              huge  **pae;
  53.  
  54.  
  55. void seg_link()
  56. {
  57.    extern word                plus1;
  58.    register s_dropped  huge   *p = ps;
  59.    register seg huge          **q;
  60.    word                       i, index;
  61.  
  62.    ENTER("seg_link");
  63.    plus1 = 0;
  64.    index = (word) (__p - __program);
  65.    if( ! sp && p->type == S_DS)
  66.       nerror("You can't start off with a .DS segment");
  67.    pas = q = nmalloc( sbytes * sizeof( seg *));
  68.  
  69.    for( i = (word) sbytes; i; i--, p++)
  70.    {            /* V--- changin' the val of s_dropped as well */
  71.       build_seg( p->index + index, p->type, p->size);
  72.       endpc += p->size;
  73.       *q++ = sp;
  74.       POINTER_CHECK( q[-1]);
  75.    }
  76.    LEAVE();
  77. }
  78.  
  79. static byte sizetab[256] =
  80. {
  81.    1,2,0,0,2,2,2,0, 1,2,1,0,3,3,3,0,
  82.    2,2,2,0,2,2,2,0, 1,3,1,0,3,3,3,0,
  83.    3,2,0,0,2,2,2,0, 1,2,1,0,3,3,3,0,
  84.    2,2,2,0,2,2,2,0, 1,3,1,0,3,3,3,0,
  85.    1,2,0,0,0,2,2,0, 1,2,1,0,3,3,3,0,
  86.    2,2,2,0,0,2,2,0, 1,3,1,0,0,3,3,0,
  87.    1,2,0,0,2,2,2,0, 1,2,1,0,3,3,3,0,
  88.    2,2,2,0,2,2,2,0, 1,3,1,0,3,3,3,0,
  89.  
  90.    2,2,0,0,2,2,2,0, 1,0,1,0,3,3,3,0,
  91.    2,2,2,0,2,2,2,0, 1,3,1,0,3,3,3,0,
  92.    2,2,2,0,2,2,2,0, 1,2,1,0,3,3,3,0,
  93.    2,2,2,0,2,2,2,0, 1,3,1,0,3,3,3,0,
  94.    2,2,0,0,2,2,2,0, 1,2,1,0,3,3,3,0,
  95.    2,2,2,0,0,2,2,0, 1,3,1,0,0,3,3,0,
  96.    2,2,0,0,2,2,2,0, 1,2,1,0,3,3,3,0,
  97.    2,2,2,0,0,2,2,0, 1,3,1,0,0,3,3,0
  98. };
  99.  
  100.  
  101. void code_reloc()
  102. {
  103.    register s_dropped huge *p = ps;
  104.    register word           rdiff = diff,
  105.                            val, i;
  106.    register byte huge      *src;
  107.    lword                   j  = sbytes;
  108.  
  109.  
  110.    ENTER("code_reloc");
  111.    while( j--)
  112.    {
  113.       src = pb + p->index;
  114. #if ! VERSION
  115.       if( j || p->type != S_DS)
  116.          POINTER_CHECK( src);
  117. #endif
  118.       POINTER_CHECK( p);
  119.       POINTER_CHECK( __p);
  120.       i = p->size;
  121.       switch( p++->type)
  122.       {
  123.          case S_RCODE :
  124.             while( i--)
  125.                switch( sizetab[ *src])
  126.                {
  127.                   case 0  :
  128.                      nferror("object code is impure");
  129.  
  130.                   case 2  :
  131.                      i--;
  132.                      deposit( *src++);
  133.                   case 1  :
  134.                      deposit( *src++);
  135.                      break;
  136.  
  137.                   case 3  :
  138.                      deposit( *src++);
  139.                      val = pdpeek( src);
  140.                      if( inrange( val, DEFORG - 1, endpc))
  141.                         val += rdiff;
  142.                      wdeposit( val);
  143.                      i -= 2;
  144.                }
  145.             break;
  146.  
  147.          case S_SDATA :
  148.             while( i--)
  149.             {
  150.                deposit( *src++);
  151.             }
  152.             continue;
  153.  
  154.          case S_RDATA :
  155.             while( i)
  156.             {
  157.                if( val = pdpeek( src))
  158.                   val += rdiff;
  159.                wdeposit( val);
  160.                i -= 2;
  161.             }
  162.             break;
  163.  
  164.          case S_TDATA :
  165.             while( i)
  166.             {
  167.                if( val = pdpeek( src))
  168.                   val += rdiff;
  169.                wddeposit( val);
  170.                i -= 2;
  171.             }
  172.          case S_RSTOP :    /* not really implemented */
  173.             break;
  174.  
  175.          case S_DS    :
  176.             if( ! bootable)
  177.             {
  178.                dpoke( ptohead, __pc - 1);
  179.                __pc += i;
  180.                dpoke( __p, __pc);
  181.                _advance( 4);
  182.                ptohead = __p - 2;
  183.             }
  184.             else
  185.             {
  186.                register int   j;
  187.  
  188.                for( j = i; j; j--)
  189.                {
  190.                   deposit( 0);
  191.                }
  192.             }
  193.             break;
  194.  
  195.          default      :
  196.             nierror("Whoa! *Serious* problems with segmentation");
  197.       }
  198.    }
  199.    LEAVE();
  200. }
  201.  
  202.  
  203. void  imm_link()
  204. {
  205.    register i_dropped huge *p = pi;
  206.    register imm huge       *q;
  207.    imm huge                **x;
  208.    register word           i, tmp;
  209.  
  210.    ENTER("imm_link");
  211.    x = pai = nmalloc( (ibytes + 1) * sizeof( imm *));
  212.    *x++ = 0;
  213.    for( i = (word) ibytes; i; p++, i--)
  214.    {
  215.       *x++ = q = imm_alloc();
  216.       POINTER_CHECK( p);
  217.       POINTER_CHECK( q);
  218.       q->block = pas[ p->block];
  219.       POINTER_CHECK( q->block);
  220.       if( q->val = p->val)
  221.          q->val += diff;
  222.       q->type = p->type;
  223.       q->offset = p->offset;
  224.       if( tmp = q->val)
  225.       {
  226.          if( q->type)
  227.             tmp >>= 8;
  228.          poke( __program + q->block->index + p->offset, tmp);
  229.       }
  230.       q->next = 0;
  231.       cip = hip ? (cip->next = q) : (hip = q);
  232.    }
  233.    LEAVE();
  234. }
  235.  
  236. /* This function is just for Debugging */
  237. #if ! VERSION
  238. void  lerr_imms()
  239. {
  240.    register imm huge *p;
  241.  
  242.    if( p = hip)
  243.       do
  244.       {
  245.          POINTER_CHECK( p);
  246.          if( ! p->val)
  247.             nierror("There are imms w/o a value");
  248.       }
  249.       while( p = p->next);
  250. }
  251. #endif
  252.  
  253. void ref_link()
  254. {
  255.    register r_dropped huge *p = pr;
  256.    register ref huge       *q, 
  257.                 huge       *old;
  258.    register word           i = (word) rbytes;
  259.  
  260.    ENTER("ref_link");
  261.    if( i = (word) rbytes)
  262.    {
  263.       POINTER_CHECK( p);
  264.       do
  265.       {
  266.          q         = ref_alloc();
  267.          POINTER_CHECK( q);
  268.          q->ref    = (expr *) *p++;      /* yet unknown */
  269.          q->hacked = 0;
  270.          old       = rhead ? (old->next = q) : (rhead = q); /* That's OK */
  271.       }
  272.       while( --i);
  273.       q->next = 0;
  274.    }
  275.    LEAVE();
  276.    ADD_WATCH( &rhead, sizeof( char *), "rhead");
  277. }
  278.  
  279.  
  280. static void  fix_link( p, q, r)
  281. register e_dropped huge *p;
  282. register expr huge      *q;
  283. register f_dropped huge *r;
  284. {
  285.    register fix huge *f = fix_alloc();
  286.  
  287.    ENTER("fix_link");
  288.    POINTER_CHECK( p);
  289.    POINTER_CHECK( q);
  290.    POINTER_CHECK( r);
  291.    POINTER_CHECK( f);
  292.    if( q->fix == FIX_LABEL)
  293.       f->poof.label = (label *) p->t;     /* yet unknown */
  294.    else
  295.       f->poof.block = pas[ (word) r->poof];
  296.    f->imm       = pai[ r->imm];
  297.    f->index     = r->index;
  298.    q->zonk.fixp = f;
  299.    LEAVE();
  300. }
  301.  
  302.  
  303. void  exp_link()
  304. {
  305.    register e_dropped huge *p;
  306.    register expr huge      *q;
  307.    register ref  huge      *x;
  308.    expr          huge      **y;
  309.    f_dropped     huge      *r;
  310.    register word           i;
  311.  
  312.    ENTER("exp_link");
  313.    if( p = pe)
  314.    {
  315.       y = pae = nmalloc( (ebytes + 1) * sizeof( expr *));
  316.       *y++ = 0;
  317.       r    = pf;
  318.  
  319.       for( i = 1; i <= ebytes; i++, p++)
  320.       {
  321.          *y++ = q = exp_alloc();
  322.          POINTER_CHECK( p);
  323.          POINTER_CHECK( q);
  324.          if( valued( p) && e_pcrel( p))
  325.             q->val = p->val + diff;
  326.          else
  327.             q->val = p->val;
  328.          q->aux   = p->aux + diff;
  329.          q->op    = p->op;
  330.          q->label = p->label;
  331.          q->l     = (expr *) p->l;     /* yet unknown */
  332.          q->r     = (expr *) p->r;     /* yet unknown */
  333.          if( q->fix = p->fix)
  334.             fix_link( p, q, r++);
  335.          else
  336.             q->zonk.t = (expr *) p->t; /* yet unknown */
  337.  
  338.  
  339.          for( x = rhead; x; x = x->next)
  340.             if( ! x->hacked && (word) x->ref == i)
  341.             {
  342.                POINTER_CHECK( x);
  343.                POINTER_CHECK( q);
  344.                x->ref    = q;
  345.                x->hacked = 1;
  346.                break;
  347.             }
  348.       }
  349.  
  350.       MESS("the second routine");
  351.       {
  352.          register expr huge   *p;
  353.          register word        i;
  354.  
  355.          for( i = (word) ebytes, y = pae + 1; i; i--, y++)
  356.          {
  357.             p = *y;
  358.             POINTER_CHECK( p);
  359.             if( ! p->fix)
  360.             {
  361. #if ! VERSION
  362.                if( p->hacked & 0x4)
  363.                   nierror("Overwriting pointer with bogus address");
  364.                p->hacked |= 0x4;
  365. #endif                     
  366.                p->zonk.t = pae[ (word) p->zonk.t];
  367.                POINTER_CHECK( p->zonk.t);
  368.             }
  369. #if ! VERSION            
  370.             if( p->hacked & 0x3)
  371.                nierror("Overwriting pointer with bogus address");
  372.             p->hacked |= 3; 
  373. #endif            
  374.             p->l = pae[ (word) p->l];
  375.             p->r = pae[ (word) p->r];
  376.             POINTER_CHECK( p->l);
  377.             POINTER_CHECK( p->r);
  378.          }
  379.       }
  380.    }
  381.    LEAVE();
  382. }
  383.  
  384.  
  385. /* ---------------------------------------------------------- */
  386. /*      The first symbol link stage. What is happening ?      */
  387. /* We already hook up the as of yet untabled symbols to the   */
  388. /* already pointered ref (excepting of course >>EXPR<<)       */
  389. /* ---------------------------------------------------------- */
  390. void  sym_link()
  391. {
  392.    register linksymbol huge   *p;
  393.    register ref        huge   *r, huge *old;
  394.    register word              i,norefs;
  395.  
  396.    ENTER("sym_link");
  397.    for( r = rhead, p = py, i = (word) ybytes; i; i--, p++)
  398.    {
  399.       MESS("loop");
  400.       POINTER_CHECK( p);
  401.       INTEGRITY_CHECK();
  402.       if( norefs = (lword) p->refs)
  403.       {
  404.          MESS("-de-loop");
  405.          for( p->refs = r; norefs > 1; r = r->next, norefs--);
  406.          POINTER_CHECK( r);
  407.          old = r;
  408.          r   = r->next;
  409.          POINTER_CHECK( r);
  410.          old->next = 0;
  411.       }
  412.       else
  413.          if( ! (p->type & L_ZERO))
  414.          {
  415.             MESS("-and-loop");
  416.             POINTER_CHECK( p);
  417.             INTEGRITY_CHECK();
  418.             p->val += diff;               /* Else update the value */
  419.             INTEGRITY_CHECK();
  420.          }
  421.    }
  422.    DEL_WATCH( &rhead);
  423.    LEAVE();
  424. }
  425.  
  426.  
  427. #define l_unvalued( x)  (x)->refs
  428. #define l_valued( x)    ! l_unvalued( x)
  429.  
  430. void sym2_link()
  431. {
  432.    register linksymbol huge   *p = py;
  433.    register label      huge   *q;
  434.    register lword             i  = ybytes;
  435.    char                       *s;
  436.  
  437.    ENTER("sym2_link");
  438.    while( i--)
  439.    {
  440.       MESS("A");
  441.       POINTER_CHECK( p);
  442.       s = str_alloc( SIGNIFICANT + 1);            /* improve dat */
  443.       {
  444.          register char huge *src = p->name,
  445.                        huge *dst = s;
  446.  
  447. #if SIGNIFICANT == 8
  448.          *dst++ = *src++;  /* SIGNIFICANT == 8 */
  449.          *dst++ = *src++;
  450.          *dst++ = *src++;
  451.          *dst++ = *src++;
  452.          *dst++ = *src++;
  453.          *dst++ = *src++;
  454.          *dst++ = *src++;
  455.          *dst++ = *src++;
  456.          *dst   =0;
  457. #else
  458.          register int   j = SIGNIFICANT;
  459.  
  460.          while( j--)
  461.             *dst++ = *src++;
  462.          *dst = 0;
  463. #endif
  464.       }
  465.       if( ! (q = find_label( s)))
  466.          (q = enter_llabel( s, p->val, p->type))->refs = p->refs;
  467.       else
  468.         if( ! (q->type & p->type & L_MASK1))
  469.             nserror( "label type mismatch", s);
  470.          else
  471.             if( l_valued( q))
  472.                if( l_valued( p))
  473.                   nserror("Doubly defined labeled", s);
  474.                else
  475.                {
  476.                   POINTER_CHECK( q);
  477.  
  478.                   /* Case: LABEL has value, we got some refs */
  479.                   q->refs = p->refs;
  480.                   entrefer( q);
  481.                }
  482.             else
  483.                if( l_valued( p))
  484.                {
  485.                   POINTER_CHECK( q);
  486.                   /* Case: Label has refs, we got the value */
  487.                   q->val  = p->val;
  488.                   entrefer( q);
  489.                }
  490.                else
  491.                {
  492.                   /* Just append our reflist */
  493.                   register ref huge  *x = q->refs;
  494.  
  495.                   POINTER_CHECK( q);
  496.                   while( x->next)
  497.                      x = x->next;
  498.                   POINTER_CHECK( x);
  499.                   x->next = p->refs;
  500.                }
  501.  
  502.       LABEL_CHECK( q);
  503.       if( l_unvalued( p))
  504.       {
  505.          register word  i;
  506.          fix huge       *f;
  507.  
  508.          for( i = (word) ebytes; i; i--)
  509.             if( pae[i]->fix == FIX_LABEL &&
  510.                 ! (f = pae[i]->zonk.fixp)->hacked &&
  511.                 (word) f->poof.label == p->no)
  512.             {
  513.                POINTER_CHECK( f);
  514.                POINTER_CHECK( q);
  515.                f->poof.label = q;
  516.                f->hacked     = 1;
  517.                break;
  518.             }
  519.       }
  520.       p++;
  521.    }
  522.    LEAVE();
  523. }
  524.  
  525.