home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 213a.lha / Sozobon-C / jas / cpy.c < prev    next >
C/C++ Source or Header  |  1996-02-14  |  4KB  |  189 lines

  1.  
  2. /*
  3.  * Copyright (c) 1988 by Sozobon, Limited.  Author: Joseph M Treat
  4.  *
  5.  * Permission is granted to anyone to use this software for any purpose
  6.  * on any computer system, and to redistribute it freely, with the
  7.  * following restrictions:
  8.  * 1) No charge may be made other than reasonable charges for reproduction.
  9.  * 2) Modified versions must be clearly marked as such.
  10.  * 3) The authors are not responsible for any harmful consequences
  11.  *    of using this software, even if they result from defects in it.
  12.  */
  13.  
  14. #include "jas.h"
  15.  
  16. #define R_ABS    0
  17. #define R_DAT    1
  18. #define R_TXT    2
  19. #define R_BSS    3
  20. #define R_EXT    4
  21. #define R_UPPER    5
  22. #define R_FIRST    7
  23.  
  24. #define RBLEN 256
  25.  
  26. typedef struct _reloc {
  27.     struct _reloc *next;
  28.     unsigned short cnt;
  29.     unsigned short reloc[RBLEN];
  30. } RELOC;
  31.     
  32. RELOC *relptr = (RELOC *) NULL;
  33. RELOC *curptr;
  34.  
  35. extern SYM dot;
  36. extern long newdot;
  37.  
  38. #define SEG(p) ( (p)->flags & SEGMT )
  39.  
  40. translate( seg, null )
  41.     unsigned short seg;
  42.     int null;
  43. {
  44.     register unsigned short stype;
  45.     register CBUF *code;
  46.     register unsigned short rval, orval;
  47.     int havebyte = 0;
  48.     int cline = 0;
  49.     extern CBUF *cget();
  50.  
  51.     if ( relptr == (RELOC *) NULL ) {
  52.         relptr = ALLO(RELOC);
  53.         curptr = relptr;
  54.     }
  55.  
  56.     rval = R_ABS;
  57.     for ( ; code = cget( seg ); newdot += code->nbits / 8 ) {
  58.         cline = code->line;
  59.         orval = rval;
  60.         rval = R_ABS;
  61.         if ( code->action == GENSTMT )
  62.             dot.value = newdot;
  63.         
  64.         stype = UNK;
  65.         if ( code->value.psym ) {
  66.             stype = SEG(code->value.psym);
  67.             switch ( stype ) {
  68.             case DAT:
  69.                 rval = R_DAT;
  70.                 break;
  71.             case TXT:
  72.                 rval = R_TXT;
  73.                 break;
  74.             case BSS:
  75.                 rval = R_BSS;
  76.                 break;
  77.             default:
  78.                 rval = R_EXT;
  79.                 break;
  80.             }
  81.             if ( code->value.psym->flags & EQUATED ) {
  82.                 stype = EQUATED;
  83.                 rval = R_ABS;
  84.             }
  85.         }
  86.         if ( code->action == GENPCREL ) {
  87.             if ( code->value.psym && stype != TXT )
  88.                 warn( cline, "illegal pc-relative reference" );
  89.             rval = R_ABS;
  90.             stype = UNK;
  91.             code->value.value -= (dot.value + 2);
  92.         }
  93.  
  94.         if ( code->value.psym ) {
  95.             if ( code->value.psym->flags & (SEGMT|EQUATED) )
  96.                 code->value.value += code->value.psym->value;
  97.         }
  98.  
  99.         /* don't check anything right now ...
  100.             chkvalue( code );
  101.         ... */
  102.  
  103.         code->value.value <<= (32 - code->nbits);
  104.         output( (char *) &code->value.value, sizeof (char),
  105.                             (int) code->nbits/8 );
  106.         if ( rval == R_EXT )
  107.             rval |= ( code->value.psym->index << 3 );
  108.  
  109.         if ( havebyte == 1 && code->nbits != 8 )
  110.             error( cline, "relocation alignment error" );
  111.         if ( havebyte == 1 && rval == R_ABS && orval == R_FIRST )
  112.             rval = R_FIRST;
  113.         if ( havebyte == 1 && rval != orval )
  114.             error( cline, "bytes not separately relocatable" );
  115.  
  116.         if ( code->action == GENSTMT && rval != R_ABS )
  117.             error( cline, "relocatable operation word" );
  118.         if ( code->action == GENSTMT )
  119.             rval = R_FIRST;
  120.         if ( code->nbits == 8 && havebyte == 0 ) {
  121.             if ( rval != R_ABS && rval != R_FIRST )
  122.                 error( cline,
  123.                     "bytes not separately relocatable" );
  124.             havebyte = 1;
  125.             continue;
  126.         }
  127.         havebyte = 0;
  128.  
  129.         if ( code->nbits == 32 ) {
  130.             addrel( R_UPPER );
  131.         }
  132.         addrel( rval );
  133.     }
  134.  
  135.     dot.value = newdot += null;
  136.     while ( null-- ) {
  137.         char zip = 0;
  138.  
  139.         output( (char *) &zip, sizeof (char), 1 );
  140.         if ( havebyte && rval != R_ABS )
  141.             error( cline, "bytes not separately relocatable" );
  142.         if ( havebyte == 0 ) {
  143.             havebyte = 1;
  144.             rval = R_ABS;
  145.             continue;
  146.         }
  147.         havebyte = 0;
  148.         addrel( rval );
  149.     }
  150.     if ( havebyte ) 
  151.         error( cline, "internal relocation alignment error" );
  152. }
  153.  
  154. addrel( rval )
  155.     unsigned short rval;
  156. {
  157.     if ( curptr->cnt == RBLEN ) {
  158.         curptr->next = ALLO(RELOC);
  159.         curptr = curptr->next;
  160.     }
  161.     curptr->reloc[curptr->cnt++] = rval;
  162. }
  163.  
  164. dumprel()
  165. {
  166.     register RELOC *rp;
  167.  
  168.     for ( rp = relptr; rp; rp = rp->next ) {
  169.         output( (char *) rp->reloc, sizeof (unsigned short),
  170.                                 (int) rp->cnt );
  171.     }
  172.     return;
  173.  
  174. chkvalue( code )
  175.     CBUF *code;
  176. {
  177.     long value;
  178.  
  179.     value = code->value.value;
  180.  
  181.     if ( code->nbits != 32 ) {
  182.         value <<= (32 - code->nbits);
  183.         value >>= (32 - code->nbits);
  184.         if ( value != code->value.value )
  185.             warn( code->line, "value overflows byte/word" );
  186.     }
  187. }
  188.