home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * Copyright (c) 1988 by Sozobon, Limited. Author: Joseph M Treat
- *
- * Permission is granted to anyone to use this software for any purpose
- * on any computer system, and to redistribute it freely, with the
- * following restrictions:
- * 1) No charge may be made other than reasonable charges for reproduction.
- * 2) Modified versions must be clearly marked as such.
- * 3) The authors are not responsible for any harmful consequences
- * of using this software, even if they result from defects in it.
- */
-
- #include "jas.h"
-
- #define R_ABS 0
- #define R_DAT 1
- #define R_TXT 2
- #define R_BSS 3
- #define R_EXT 4
- #define R_UPPER 5
- #define R_FIRST 7
-
- #define RBLEN 256
-
- typedef struct _reloc {
- struct _reloc *next;
- unsigned short cnt;
- unsigned short reloc[RBLEN];
- } RELOC;
-
- RELOC *relptr = (RELOC *) NULL;
- RELOC *curptr;
-
- extern SYM dot;
- extern long newdot;
-
- #define SEG(p) ( (p)->flags & SEGMT )
-
- translate( seg, null )
- unsigned short seg;
- int null;
- {
- register unsigned short stype;
- register CBUF *code;
- register unsigned short rval, orval;
- int havebyte = 0;
- int cline = 0;
- extern CBUF *cget();
-
- if ( relptr == (RELOC *) NULL ) {
- relptr = ALLO(RELOC);
- curptr = relptr;
- }
-
- rval = R_ABS;
- for ( ; code = cget( seg ); newdot += code->nbits / 8 ) {
- cline = code->line;
- orval = rval;
- rval = R_ABS;
- if ( code->action == GENSTMT )
- dot.value = newdot;
-
- stype = UNK;
- if ( code->value.psym ) {
- stype = SEG(code->value.psym);
- switch ( stype ) {
- case DAT:
- rval = R_DAT;
- break;
- case TXT:
- rval = R_TXT;
- break;
- case BSS:
- rval = R_BSS;
- break;
- default:
- rval = R_EXT;
- break;
- }
- if ( code->value.psym->flags & EQUATED ) {
- stype = EQUATED;
- rval = R_ABS;
- }
- }
- if ( code->action == GENPCREL ) {
- if ( code->value.psym && stype != TXT )
- warn( cline, "illegal pc-relative reference" );
- rval = R_ABS;
- stype = UNK;
- code->value.value -= (dot.value + 2);
- }
-
- if ( code->value.psym ) {
- if ( code->value.psym->flags & (SEGMT|EQUATED) )
- code->value.value += code->value.psym->value;
- }
-
- /* don't check anything right now ...
- chkvalue( code );
- ... */
-
- code->value.value <<= (32 - code->nbits);
- output( (char *) &code->value.value, sizeof (char),
- (int) code->nbits/8 );
- if ( rval == R_EXT )
- rval |= ( code->value.psym->index << 3 );
-
- if ( havebyte == 1 && code->nbits != 8 )
- error( cline, "relocation alignment error" );
- if ( havebyte == 1 && rval == R_ABS && orval == R_FIRST )
- rval = R_FIRST;
- if ( havebyte == 1 && rval != orval )
- error( cline, "bytes not separately relocatable" );
-
- if ( code->action == GENSTMT && rval != R_ABS )
- error( cline, "relocatable operation word" );
- if ( code->action == GENSTMT )
- rval = R_FIRST;
- if ( code->nbits == 8 && havebyte == 0 ) {
- if ( rval != R_ABS && rval != R_FIRST )
- error( cline,
- "bytes not separately relocatable" );
- havebyte = 1;
- continue;
- }
- havebyte = 0;
-
- if ( code->nbits == 32 ) {
- addrel( R_UPPER );
- }
- addrel( rval );
- }
-
- dot.value = newdot += null;
- while ( null-- ) {
- char zip = 0;
-
- output( (char *) &zip, sizeof (char), 1 );
- if ( havebyte && rval != R_ABS )
- error( cline, "bytes not separately relocatable" );
- if ( havebyte == 0 ) {
- havebyte = 1;
- rval = R_ABS;
- continue;
- }
- havebyte = 0;
- addrel( rval );
- }
- if ( havebyte )
- error( cline, "internal relocation alignment error" );
- }
-
- addrel( rval )
- unsigned short rval;
- {
- if ( curptr->cnt == RBLEN ) {
- curptr->next = ALLO(RELOC);
- curptr = curptr->next;
- }
- curptr->reloc[curptr->cnt++] = rval;
- }
-
- dumprel()
- {
- register RELOC *rp;
-
- for ( rp = relptr; rp; rp = rp->next ) {
- output( (char *) rp->reloc, sizeof (unsigned short),
- (int) rp->cnt );
- }
- return;
- }
-
- chkvalue( code )
- CBUF *code;
- {
- long value;
-
- value = code->value.value;
-
- if ( code->nbits != 32 ) {
- value <<= (32 - code->nbits);
- value >>= (32 - code->nbits);
- if ( value != code->value.value )
- warn( code->line, "value overflows byte/word" );
- }
- }
-