home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
compiler
/
nasm20b
/
nasm_src
/
load.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-19
|
11KB
|
425 lines
/* ---------------------------------------------------------------------- */
/* 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");
}
}