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

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1991 by Natürlich!                     */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. #define LINKER       1
  7. #define WRITE_TABLE  0
  8. #if WRITE_TABLE
  9. # include <stdio.h>
  10. #endif
  11. #include "defines.h"
  12. #include "nasm.h"
  13. #include OSBIND
  14. #include "debug.h"
  15. #include "seg.h"
  16. #include "labels.h"
  17. #include "imm.h"
  18. #include "process.h"
  19.  
  20. extern imm huge   *hip;
  21. extern seg huge   *h_seg, huge *l_seg;
  22. seg huge          *f_seg;
  23. extern word       r_end, r_start, rcode_off;
  24.  
  25. #define xdeposit( x)     deposit( x)
  26. #define xwdeposit( x)    wdeposit( x)
  27.  
  28.  
  29. void def_label( s, val)
  30. char  *s;
  31. word  val;
  32. {
  33.    label huge  *q;
  34.  
  35.    if( ! (q = find_label( s)))
  36.    {
  37. #if ! VERSION
  38.       extern char    *str_alloc();
  39.       
  40.       s = strcpy( str_alloc( strlen( s) + 1), s);
  41. #endif   
  42.       enter_llabel( s, val, L_PC);  /* Shouldn't really happen */
  43.    }      
  44.    else
  45.       if( ! q->refs)
  46.          nierror("Linker internal label twice defined");
  47.       else
  48.       {
  49.          q->val = val;     /* Case: Label has refs, we got the value */
  50.          entrefer( q);
  51.       }
  52. }
  53.  
  54. static int  countem( p, ourpage, type)
  55. register imm huge *p;
  56. word              ourpage;
  57. int               type;
  58. {
  59.    register int   i;
  60.    register word  tmp;
  61.    
  62.    for( i = 0; p; p = p->next)
  63.       if( p->type == type && p->block != f_seg)
  64.       {
  65.          if( (tmp = p->offset + p->block->offset - rcode_off + r_start) 
  66.                >= r_end || 
  67.              (tmp & 0xFF00) > ourpage)
  68.             break;
  69.          i++;
  70.       }
  71.    return( i);
  72. }
  73.  
  74. /* ---------------------------------------------------------- */
  75. /*   This dumps the immediate table down into the file write  */
  76. /*   space. The flag tells us whether we are gonna be         */
  77. /*   page-aligned or not (then we need plenty more info)      */
  78. /* ---------------------------------------------------------- */
  79. #define MSB    1
  80. #define LSB    0
  81.  
  82. void dump_imm( flag)
  83. int  flag;
  84. {
  85.    register imm huge *p = hip;
  86.    register word     i;
  87.    word              pages, ourpage, 
  88.                      factor = (r_start & 0xFF) - rcode_off;
  89. #if WRITE_TABLE
  90.    word              aux, cnt;
  91. #endif   
  92.  
  93.    f_seg = l_seg->next;
  94.    def_label("|IMMTAB", __pc);
  95.  
  96.    /* incorporate .DS holes into index */
  97. /*   {
  98.       register seg huge *p;
  99.       register word     plus = 0;
  100.       
  101.       for( p = h_seg; p != f_seg; p = p->next)
  102.       {
  103.          p->index += plus;
  104.          if( p->type == S_DS)
  105.             plus += p->size;
  106.       }
  107.    }*/
  108.          
  109.    pages = ( ((r_end & 0xFF00) - (ourpage = r_start & 0xFF00)) >> 8) + 1;
  110. #if WRITE_TABLE
  111.    printf(  "%d pages total\n", pages);
  112. #endif   
  113.    xdeposit( pages);
  114.    
  115.    if( ! flag)
  116.    {
  117.       int   ipages = pages;
  118.       
  119. #if WRITE_TABLE
  120.       printf( "LSB patch bytes:");
  121.       aux = r_start & 0xFF00; 
  122. #endif
  123.       while( ipages--)
  124.       {
  125.          i = countem( p, ourpage, LSB);
  126.          xdeposit( i);
  127. #if WRITE_TABLE
  128.          printf( "\n%4d bytes to patch\n", i);
  129.          cnt = 0;
  130. #endif
  131.          while( i--)
  132.          {
  133.             while( p->type)
  134.                p = p->next;
  135.             xdeposit( p->offset + p->block->offset + factor);
  136. #if WRITE_TABLE
  137.             if( cnt++ == 8)
  138.             {
  139.                putchar('\n');
  140.                cnt = 0;
  141.             }
  142.             printf(  "   $%04X", __p[ -1] + ourpage);
  143.             if( i && cnt != 8)
  144.                putchar( ',');
  145. #endif
  146.             p = p->next;
  147.          }
  148.          ourpage += 0x100;
  149. #if WRITE_TABLE
  150.          putchar('\n');
  151. #endif         
  152.       }
  153.       p = hip;
  154.       ourpage = r_start & 0xFF00;
  155.    }
  156.  
  157. #if WRITE_TABLE
  158.    printf( "\n\nMSB patch bytes:");
  159. #endif
  160.    while( pages--)
  161.    {
  162.       i = countem( p, ourpage, MSB);
  163.       xdeposit( i);
  164. #if WRITE_TABLE
  165.          printf( "\n%4d bytes to patch\n", i);
  166.          cnt = 0;
  167. #endif
  168.       while( i--)
  169.       {
  170.          while( ! p->type)
  171.             p = p->next;
  172.          xdeposit( p->offset + p->block->offset + factor);
  173. #if WRITE_TABLE
  174.          if( cnt++ == 3)
  175.          {
  176.             putchar('\n');
  177.             cnt = 1;
  178.          }
  179.          printf( "   $%04X (LSB: $%02X)", __p[ -1] + ourpage, 
  180.                   p->val & 0xFF);
  181.          if( i && cnt != 3)
  182.             putchar( ',');
  183. #endif
  184.          if( ! flag)
  185.          {
  186.             xdeposit( p->val);
  187.          }
  188.          p = p->next;
  189.       }
  190.       ourpage += 0x100;
  191. #if WRITE_TABLE
  192.       putchar('\n');
  193. #endif         
  194.    }
  195. }
  196.  
  197.  
  198. void dump_reloc()
  199. {
  200.    register seg huge *p = h_seg;
  201.  
  202.    def_label( "|RELTAB", __pc);
  203.    for(;;)
  204.    {
  205.       if( p->type == S_DS)
  206.       {
  207.          xdeposit( S_SDATA); 
  208.       }
  209.       else
  210.       {
  211.          xdeposit( p->type);
  212.          while( p != l_seg && p->next->type == p->type)
  213.          { 
  214.             p->next->size += p->size;
  215.             p = p->next;
  216.          }
  217.       }
  218.       xwdeposit( p->size);
  219.       if( p == l_seg)
  220.       {
  221.          xdeposit( 128);    /* dump EOP */
  222.          return;
  223.       }
  224.       p = p->next;
  225.    }
  226. }
  227.  
  228.