home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* Copyright (C) 1991 by Natürlich! */
- /* This file is copyrighted! */
- /* Refer to the documentation for details. */
- /* ---------------------------------------------------------------------- */
- #define LINKER 1
- #include "defines.h"
- #include <stdio.h>
- #include OSBIND
- #include "nasm.h"
- #include "debug.h"
- #include "ldebug.h"
- #include NMALLOC_H
- #include "object.h"
- #include "process.h"
- #include "code.h"
-
- #if ! VERSION
- extern char x1[], x2[], x3[], x4[], x5[], x6[];
- #endif
-
- byte huge *pb;
- e_dropped huge *pe;
- s_dropped huge *ps;
- linksymbol huge *py;
- i_dropped huge *pi;
- r_dropped huge *pr;
- f_dropped huge *pf;
- lword magic, bytes, sbytes, ibytes, rbytes, ebytes, ybytes, fbytes;
- lword ysize; /* hack for backwards compatibility */
- static obj_h l;
-
- word version,
- alignment;
- #if ! VERSION
- static word revision;
- #endif
- static void fix_version(), fix_sizes();
- #if ! DISASM
- extern int relocatable,
- bootable,
- verbose,
- pageflag;
- extern word diff, head_off, endpc, origin, mv_offset;
-
- extern byte huge *ptohead;
-
- #endif
- char trc_loss[] = "File is truncated";
-
-
- #if VERSION
- # define the_10seek( x, y)
- #else
-
- void the_10seek( fd, x)
- char *x;
- {
- unsigned long foo;
- static char chkbuf[11];
-
- if( (foo = Fread( fd, 10L, chkbuf)) < 10L)
- {
- fprintf( stderr, "FOO = %ld\n", foo);
- ngferror( foo, trc_loss);
- }
- if( strcmp( chkbuf, x))
- nferror("Not a good object file");
- }
- #endif
-
- void do_load( fd)
- {
- long foo;
-
- ENTER("do_load");
- INTEGRITY_CHECK();
- if( Fread( fd, sizeof( obj_h), &l) != sizeof( obj_h))
- nferror("File is too short to be an object file");
- IMESS("Sizeof( obj_h) = %ld", sizeof( obj_h), 4);
- magic = lbeek( &l.magic);
- version = dbeek( &l.version);
- #if ! VERSION
- revision = dbeek( &l.revision);
- #endif
- alignment= dbeek( &l.alignment);
- bytes = (lword) dbeek( &l.codesize);
- sbytes = lbeek( &l.segsize);
- ibytes = lbeek( &l.immsize);
- rbytes = lbeek( &l.relsize);
- ebytes = lbeek( &l.expsize);
- ybytes = ysize = lbeek( &l.symsize);
- fbytes = lbeek( &l.fixsize);
- if( magic != OBJMAGIC)
- nferror("This is not an object file");
- if( version < (word) OBJ_READ_COMP)
- nferror("Object file was created with an obsolete version");
- if( version > DVERSION)
- nferror("I am too oldfashioned to understand this object format");
- #if ! VERSION
- if( revision != ASMREVISION)
- nferror("Object was created by a different revision");
- #endif
- if( version != DVERSION)
- fix_sizes( version);
-
- #if ! DISASM
- if( __p - __program + bytes >= MAXMODULE)
- nferror("Objects overflow the program buffer");
- #endif
- MESS("[ 0] --- Fread ---");
- pb = nmalloc( bytes);
- if( (foo = Fread( fd, bytes, pb)) != bytes)
- ngferror( foo, trc_loss);
-
- MESS("[ 1] --- Fseek ---");
- the_10seek( fd, x1);
- INTEGRITY_CHECK();
- MESS("[ 2] --- Sbytes ---");
- if( sbytes)
- {
- ps = nmalloc( sbytes);
- if( (foo = Fread( fd, sbytes, ps)) != sbytes)
- ngferror( foo, trc_loss);
- }
-
- MESS("[ 3] --- Fseek ---");
- INTEGRITY_CHECK();
- the_10seek( fd, x2);
- MESS("[ 4] --- Ibytes ---");
- if( ibytes)
- {
- pi = nmalloc( ibytes);
- if( (foo = Fread( fd, ibytes, pi)) != ibytes)
- ngferror( foo, trc_loss);
- }
-
- MESS("[ 5] --- Fseek ---");
- INTEGRITY_CHECK();
- the_10seek( fd, x3);
- MESS("[ 6] --- Rbytes ---");
- if( rbytes)
- {
- pr = nmalloc( rbytes);
- if( (foo = Fread( fd, rbytes, pr)) != rbytes)
- ngferror( foo, trc_loss);
- }
-
- MESS("[ 7] --- Fseek ---");
- INTEGRITY_CHECK();
- the_10seek( fd, x4);
- MESS("[ 8] --- Ebytes ---");
- if( ebytes)
- {
- pe = nmalloc( ebytes);
- if( (foo = Fread( fd, ebytes, pe)) != ebytes)
- ngferror( foo, trc_loss);
- }
-
- MESS("[ 9] --- Fseek ---");
- the_10seek( fd, x5);
- MESS("[10] --- Ybytes ---");
- if( ybytes)
- {
- py = nmalloc( ysize);
- if( (foo = Fread( fd, ybytes, py)) != ybytes)
- ngferror( foo, trc_loss);
- }
-
- the_10seek( fd, x6);
- INTEGRITY_CHECK();
- MESS("[11] --- Fbytes ---");
- if( fbytes)
- {
- pf = nmalloc( fbytes);
- if( (foo = Fread( fd, fbytes, pf)) != fbytes)
- ngferror( foo, trc_loss);
- }
-
- ADD_WATCH( &pb, sizeof( char *), "pb");
- ADD_WATCH( &pe, sizeof( char *), "pe");
- ADD_WATCH( &ps, sizeof( char *), "ps");
- ADD_WATCH( &py, sizeof( char *), "py");
- ADD_WATCH( &pi, sizeof( char *), "pi");
- ADD_WATCH( &pr, sizeof( char *), "pr");
- ADD_WATCH( &pf, sizeof( char *), "pf");
-
- if( version != DVERSION)
- {
- fix_version( version); /* fix up old style object files */
- }
-
- ybytes /= sizeof( linksymbol);
- ebytes /= sizeof( e_dropped);
- sbytes /= sizeof( s_dropped);
- ibytes /= sizeof( i_dropped);
- rbytes /= sizeof( r_dropped);
- fbytes /= sizeof( f_dropped);
-
-
- INTEGRITY_CHECK();
- # if BIGENDIAN
- flipstructs();
- # endif
- INTEGRITY_CHECK();
- #if ! DISASM
- {
- word oldpc,
- val = 0;
-
- diff = __pc - DEFORG + mv_offset;
- oldpc = __pc;
- if( alignment)
- if( ! pageflag && relocatable)
- nferror("Conflict between -m option and requested alignment");
- else
- if( val = __pc & alignment)
- {
- dpoke( ptohead, __pc - 1);
- __pc += (val = (~val & alignment) + 1);
- diff += val;
- if( bootable)
- {
- register int i;
-
- for( i = val; i; i--)
- *__p++ = 0;
- }
- else
- {
- dpoke( __p, __pc);
- _advance( 4);
- ptohead = __p - 2;
- }
- }
- endpc = DEFORG;
-
- INTEGRITY_CHECK();
- seg_link();
- INTEGRITY_CHECK();
- MESS("code_reloc");
- code_reloc();
- INTEGRITY_CHECK();
- MESS("imm_link");
- imm_link();
- INTEGRITY_CHECK();
- MESS("ref_link");
- ref_link();
- INTEGRITY_CHECK();
- MESS("exp_link");
- exp_link();
- INTEGRITY_CHECK();
- MESS("sym_link");
- sym_link();
- INTEGRITY_CHECK();
- MESS("sym2_link");
- sym2_link();
- INTEGRITY_CHECK();
- DEL_WATCH( &pb);
- DEL_WATCH( &pe);
- DEL_WATCH( &ps);
- DEL_WATCH( &py);
- DEL_WATCH( &pi);
- DEL_WATCH( &pr);
- DEL_WATCH( &pf);
- wrapup();
-
- if( verbose)
- if( alignment)
- printf("Start: $%04X Size:%5ld bytes Alignment loss: %3d bytes\n",
- oldpc, (lword) __pc - oldpc, val);
- else
- printf("Start: $%04X Size:%5ld bytes\n", oldpc, bytes);
-
- }
- #endif
- LEAVE();
- }
-
- #if BIGENDIAN
- void flipstructs()
- {
- register word huge *q;
- register lword i;
- {
- register linksymbol huge *p;
-
- for( p = py, i = ybytes; i--; p++)
- {
- q = (word huge *) p;
- dswap( q); q++;
- dswap( q); q++;
- dswap( q); q += 2;
- lswap( q);
- POINTER_CHECK( q);
- }
- }
- {
- for( q = (word huge *) pe, i = ebytes; i--;)
- {
- dswap( q); q++; /* val */
- dswap( q); q++; /* aux */
- dswap( q); /* label */
- q += 2; /* op & fix */
- dswap( q); q++; /* t */
- dswap( q); q++; /* l */
- POINTER_CHECK( q);
- dswap( q); q++; /* r */
- }
- }
- {
- for( q = (word huge *) pi, i = ibytes; i--;)
- {
- dswap( q); q++; /* block */
- dswap( q); q++; /* type */
- dswap( q); q++; /* offset*/
- POINTER_CHECK( q);
- dswap( q); q++; /* val */
- }
- }
- {
- for( q = (word huge *) ps, i = sbytes; i--;)
- {
- dswap( q); q++; /* type */
- dswap( q); q++; /* index */
- POINTER_CHECK( q);
- dswap( q); q++; /* size */
- }
- }
- {
- for( q = (word huge *) pf, i = fbytes; i--;)
- {
- dswap( q); q++; /* poof */
- dswap( q); q++; /* imm */
- POINTER_CHECK( q);
- dswap( q); q++; /* index */
- }
- }
- {
- register r_dropped huge *p;
-
- for( p = pr, i = rbytes; i--; p++)
- {
- dswap( p);
- POINTER_CHECK( p);
- }
- }
- }
- #endif
-
- #if VERSION == 2 || VERSION == 0
- # define V1_SIGNIFICANT 8
- # define V1_SIGNDIFF (SIGNIFICANT - V1_SIGNIFICANT)
- # define V1_L_DIFF (V1_SIGNDIFF + sizeof( word))
- # define V1_SIZE (sizeof( linksymbol) - V1_L_DIFF)
- #endif
-
- static void fix_sizes( version)
- {
- switch( version)
- {
- #if VERSION == 2 || VERSION == 0
- case 1 :
- ysize = ybytes / V1_SIZE * sizeof( linksymbol);
- break;
- #endif
- default :
- nferror( "Sorry, but that's an object file version I can't cope with");
- }
- }
-
-
- static void fix_version( version)
- {
- switch( version)
- {
- #if VERSION == 2 || VERSION == 0
- case 1 :
- {
- word huge *p;
- linksymbol huge *q;
- register word i, j;
- register char huge *dst;
-
- i = ybytes /= V1_SIZE; /* calc # symbols */
- q = &py[ i]; /* move to end of */
- p = (word huge *) ((char huge *) q - i * V1_L_DIFF);
-
- while( --q, i--)
- {
- for( dst = &q->name[ j = SIGNIFICANT]; j-- > V1_SIGNIFICANT;)
- *--dst = 0;
- # if PHILOSOPHICAL_PROBLEM
- do
- {
- p = (word huge *) ((char huge *) p - 1);
- *--dst = *p;
- }
- while( j--);
- p -= sizeof( lword) / sizeof( word);
- q->refs = (ref huge *) *(lword huge *)p;
- # else
- do
- *--dst = *--(char huge *)p;
- while( j--);
- q->refs = (ref huge *) *(--(lword huge *)p);
- # endif
- q->type = *--p;
- q->no = *--p;
- q->val = *--p;
- POINTER_CHECK( p);
- POINTER_CHECK( q);
- }
- ybytes *= sizeof( linksymbol);
- break;
- }
- #endif
-
- default :
- nferror( "Sorry, but that's an object file version I can't cope with");
- }
- }
-
-
-