home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 1
/
crawlyvol1.bin
/
program
/
compiler
/
nasm20b
/
nasm_src
/
libwork.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-19
|
17KB
|
671 lines
/* ---------------------------------------------------------------------- */
/* Copyright (C) 1991 by Natürlich! */
/* This file is copyrighted! */
/* Refer to the documentation for details. */
/* ---------------------------------------------------------------------- */
#define LIBRARIAN 1
#define __BIG_GENERATOR__
#include "defines.h"
#include "nasm.h"
#include <stdio.h>
#include <stdlib.h>
#include "debug.h"
#include "object.h"
#include "lib.h"
#if OS != TOS
# include <time.h>
# if OS == UNIX
# include <sys/time.h>
# endif
#endif
#include OSBIND
#include NMALLOC_H
#include "code.h"
#include "ldebug.h"
#if ! VERSION
extern char x1[], x2[], x3[], x4[], x5[], x6[];
char y1[] = " _GLOBALS ",
y2[] = " _F_INDEX ",
y3[] = " _OBJFILE ";
#endif
byte huge *__program, huge *__p, huge *ptohead;
byte __c;
word __pc, __x;
lword __lx;
static char trc_loss[] = "File is truncated";
static linksymbol huge *py;
static obj_h l;
static char huge *space;
static char huge *p_space, huge *old_p_space;
int version;
#if ! VERSION
int revision;
#endif
word gindex, findex;
static lword bytes, sbytes, ibytes, rbytes, ebytes, ybytes, fbytes;
static lword magic, gbytes, xbytes, cbytes, size, tbytes;
static lword gsize;
g_table globals[ MAXGLOBALS];
f_table files[ MAXFILES];
extern char *currfile;
extern int laber;
extern void fix_lversion(), fix_lsizes();
#if BIGENDIAN
extern void flip_libstructs();
#endif
#if VERSION
# undef LIBMAX
# define LIBMAX 0x4000L
#endif
#define SPARE 0x8000L
void pro_init()
{
extern char outofmem[];
#if OS == TOS
if( (size = (long) Malloc( -1L)) < SPARE)
nferror("Space dangerously low *ouch* in here, aborting...");
p_space = space = nmalloc( size -= SPARE); /* leave 32K for symbols */
#else
# if OS == UNIX || OS == AMIGA
p_space = space = nmalloc( size = LIBMAX); /* ARGH! */
# else
# if OS == MSDOS
if( ! (p_space = space = nmalloc( size = LIBMAX)))
nferror( outofmem);
# else
# error "missing code for your machinery"
# endif
# endif
#endif
if( laber)
fprintf( ESTREAM, "%ld bytes space allocated for modules\n", size);
}
void pro_exit()
{
}
#if VERSION
#define thel10seek( x, y)
#else
void thel10seek( i, x)
char *x;
{
unsigned long foo;
static char chkbuf[11];
if( (foo = Fread( i, 10L, chkbuf)) < 10)
ngferror( foo, trc_loss);
if( strcmp( chkbuf, x))
nferror("Not a good NASM library file");
bcopy( chkbuf, p_space, 10L);
p_space += 10;
}
#endif
int lload( afile)
char *afile; /* 3 'V's: Van Halen, VfL und Veltins! */
{
static lib_h l;
register long foo;
int fd;
ENTER("lload");
#if LOWERFILE
downcase( afile);
#endif
IMESS( "Trying to open \"%s\" ", (long) afile, 4);
if( (fd = (int) Fopen( afile, 0)) < 0)
{
if( fd == -35)
nferror("Out of GEMDOS file handles (that's strange..) ?");
return( 0);
}
if( Fread( fd, sizeof( lib_h), &l) != sizeof( lib_h))
nferror("File is too short to be a library");
IMESS("Sizeof( lib_h) = %ld", (long) sizeof( lib_h), 4);
magic = lbeek( &l.magic);
version = dbeek( &l.version);
#if ! VERSION
revision = dbeek( &l.revision);
#endif
gbytes = gsize = lbeek( &l.gbytes);
xbytes = lbeek( &l.xbytes);
cbytes = lbeek( &l.cbytes);
if( magic != LIBMAGIC)
nferror("This is not a library");
#if BIGENDIAN
if( version < DVERSION)
#else
if( version < LIB_READ_COMP)
#endif
nferror("Library was created with an obsolete version");
if( version > DVERSION)
nferror("Librarian is too oldfashioned to understand object format");
#if ! VERSION
if( revision != LIBREVISION)
nferror("Library revision differs");
#endif
if( version != DVERSION)
fix_lsizes( version, &gsize);
thel10seek( fd, y1);
if( (foo = Fread( fd, gbytes, globals)) != gbytes)
ngferror( foo, trc_loss);
thel10seek( fd, y2);
if( xbytes)
if( (foo = Fread( fd, xbytes, &files[0])) != xbytes)
ngferror( foo, trc_loss);
thel10seek( fd, y3);
if( cbytes)
{
if( (foo = Fread( fd, cbytes, space)) != cbytes)
ngferror( foo, trc_loss);
p_space += cbytes;
}
else
p_space = space;
Fclose( fd);
if( version != DVERSION)
fix_lversion( version, &gbytes, globals);
gindex = (word) (gbytes / sizeof( g_table));
findex = (word) (xbytes / sizeof( f_table));
#if BIGENDIAN
flip_libstructs( gindex, findex, globals, files);
#endif
if( laber)
fprintf( ESTREAM, "Read in %s: %d modules with %d globals \
worth %ld bytes total\n", afile, findex, gindex, cbytes);
LEAVE();
return(1);
}
void wrapup()
{
nfree( py);
}
void file_lib( currfile)
char *currfile;
{
register char huge *src,
huge *dst;
register int i = FSIGNIFICANT;
register f_table huge *p = &files[ findex++];
ENTER("file_lib");
src = get_filename( currfile);
dst = p->name;
while( (*dst++ = *src++) && i--);
while( i--)
*dst++ = 0;
if( laber)
fprintf( ESTREAM, "Put %.32s into library [%ld bytes]\n",
currfile, tbytes);
p->seek = old_p_space - space;
#if OS == TOS
p->time = Tgettime();
p->date = Tgetdate();
#else
# if OS == MSDOS
{
struct time watch;
struct date calendar;
gettime( &watch);
getdate( &calendar);
p->time = ((unsigned) watch.ti_sec >> 1) |
((unsigned) watch.ti_min << 5) |
((unsigned) watch.ti_hour << 11);
p->date = ((unsigned) calendar.da_year - 1980 << 9) |
((unsigned) calendar.da_mon - 1 << 5) |
((unsigned) calendar.da_day - 1);
}
# else
{
struct tm *watch;
time_t the_time;
if( (the_time = time( NULL)) == -1)
nferror("Your system rudely refuses to give the current time");
watch = localtime( &the_time);
p->time = ((unsigned) watch->tm_sec >> 1) |
((unsigned) watch->tm_min << 5) |
((unsigned) watch->tm_hour << 11);
p->date = ((unsigned) watch->tm_year - 1900 << 9) |
((unsigned) watch->tm_mon << 5) |
watch->tm_mday;
}
# endif
#endif
p->bytes = tbytes;
LEAVE();
}
int check_double( name)
register char *name;
{
register char huge *s;
register g_table huge *p = &globals[0];
register int i = gindex, j;
static char buf[ SIGNIFICANT + 1];
while( i--)
{
s = p++->name;
j = 0;
while( *s++ == name[j++] && j < SIGNIFICANT);
if( j >= SIGNIFICANT)
{
for( j = 0; j != SIGNIFICANT; buf[j++] = name[j]);
buf[ SIGNIFICANT] = 0;
nserror( "Symbol is already in the library", buf);
return( 1);
}
}
return(0);
}
void sym_lib()
{
register linksymbol huge *p = py;
register char huge *dst,
huge *src;
register word i = (word) ybytes;
int entered = 0;
ENTER("sym_lib");
while( i--)
{
if( ! p->refs && ! check_double( p->name))
{
if( gindex >= MAXGLOBALS)
nferror("Sorry, global symbol table space exhausted");
dst = globals[ gindex].name;
src = p->name;
#if SIGNIFICANT == 8
*dst++ = *src++; /* SIGNIFICANT == 8 */
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++; /* eliminated one copy here */
*dst = *src;
#else
{
register int j = SIGNIFICANT;
while( j--)
*dst++ = *src++;
}
#endif
entered++;
globals[ gindex++].index = findex;
}
p++;
}
if( ! entered)
nferror("Module's unusuable 'coz there's no global label w/value");
LEAVE();
}
#if VERSION
# define S10EEKS 0
#else
# define S10EEKS 6 * 10L
#endif
void oload( afile)
char *afile; /* 3 'V's: Van Halen, VfL und Veltins! */
{
register char *x;
register long foo;
int i;
ENTER("oload");
#if LOWERFILE
downcase( afile);
#endif
IMESS( "Trying to open \"%s\" ", (long) afile, 4);
if( (i = (int) Fopen( afile, 0)) < 0)
{
MESS("Open failed");
strcpy( x = nmalloc( strlen( afile) + 5L), afile);
complete( x, ".o65", 1);
afile = x;
if( (i = (int) Fopen( x, 0)) < 0)
{
if( i == -35)
nferror("Out of GEMDOS file handles (that's strange..) ?");
nferror( "Object file does not exist");
}
}
if( Fread( i, sizeof( obj_h), &l) != sizeof( obj_h))
nferror("File is too short to be an object file");
IMESS("Sizeof( obj_h) = %ld", (long) sizeof( obj_h), 4);
magic = lbeek( &l.magic);
version = dbeek( &l.version);
#if ! VERSION
revision = dbeek( &l.revision);
#endif
bytes = (lword) dbeek( &l.codesize);
sbytes = lbeek( &l.segsize);
ibytes = lbeek( &l.immsize);
rbytes = lbeek( &l.relsize);
ebytes = lbeek( &l.expsize);
ybytes = lbeek( &l.symsize);
fbytes = lbeek( &l.fixsize);
if( magic != OBJMAGIC)
nferror("This is not an object file");
if( version < DVERSION)
nferror("Object file was created with an obsolete version");
if( version > DVERSION)
nferror("Librarian is to oldfashioned to understand this object format");
#if ! VERSION
if( revision != ASMREVISION)
nferror("Object file was made under old revision");
#endif
if( ! ybytes)
nwarning("Object file contains no global symbols");
tbytes = sbytes + ibytes + rbytes + ebytes + ybytes + fbytes + S10EEKS +
bytes + sizeof( obj_h);
if( ((old_p_space = p_space) - space) + tbytes > size)
nferror("Can't fit all these files into memory");
bcopy( &l, p_space, (long) sizeof( obj_h));
p_space += sizeof( obj_h);
if( (foo = Fread( i, bytes, p_space)) != bytes)
ngferror( foo, trc_loss);
p_space += bytes;
thel10seek( i, x1);
if( sbytes)
{
if( (foo = Fread( i, sbytes, p_space)) != sbytes)
ngferror( foo, trc_loss);
p_space += sbytes;
}
thel10seek( i, x2);
if( ibytes)
{
if( (foo = Fread( i, ibytes, p_space)) != ibytes)
ngferror( foo, trc_loss);
p_space += ibytes;
}
thel10seek( i, x3);
if( rbytes)
{
if( (foo = Fread( i, rbytes, p_space)) != rbytes)
ngferror( foo, trc_loss);
p_space += rbytes;
}
thel10seek( i, x4);
if( ebytes)
{
if( (foo = Fread( i, ebytes, p_space)) != ebytes)
ngferror( foo, trc_loss);
p_space += ebytes;
}
thel10seek( i, x5);
if( ybytes)
{
py = nmalloc( ybytes);
if( (foo = Fread( i, ybytes, py)) != ybytes)
ngferror( foo, trc_loss);
bcopy( py, p_space, ybytes);
p_space += ybytes;
}
thel10seek( i, x6);
if( fbytes)
{
if( (foo = Fread( i, fbytes, p_space)) != fbytes)
ngferror( foo, trc_loss);
p_space += fbytes;
}
ybytes /= sizeof( linksymbol);
#if BIGENDIAN
fliplinks();
#endif
LEAVE();
}
#if BIGENDIAN
void fliplinks()
{
register lword i;
register word huge *q;
register linksymbol huge *p;
for( p = py, i = ybytes; i--; p++)
{
q = (word *) p;
dswap( q); q++; /* val */
dswap( q); q++; /* no */
dswap( q); q++; /* type */
q++; /* dummy */
lswap( q); /* refs */
POINTER_CHECK( q);
}
}
#endif
void extract( afile)
char *afile;
{
long size;
int fp, i;
for( i = findex; i--;)
if( ! strcmp( files[i].name, afile))
{
if( (fp = (int) Fkreate( currfile = afile, 0x664)) < 0)
ngferror( fp, "Couldn't create output file");
if( Fwrite( fp, (size = files[i].bytes), space + files[ i].seek)
!= size)
nferror("out of space");
Fclose( fp);
return;
}
nserror("Module unknown", afile);
}
static char *months[] =
{
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
void list( flag)
{
int i;
unsigned j, k;
printf("Modules in library:\n");
for( i = 0; i != findex; i++)
{
register f_table *p = &files[ i];
j = p->time;
k = p->date;
printf("%5.5ld bytes [%2.2d:%2.2d-%2.2d.%s.%d] : %-32s \n",
p->bytes,
j >> 11, (j >> 5) & 0x3F,
k & 0x1F, months[ ((k >> 5) & 0xF) - 1], 1980 + (k >> 9),
p->name);
if( flag)
{
for( k = j = 0; j != gindex; j++)
if( globals[ j].index == i)
{
if( ! k)
putchar('\t');
printf("%-8s ", globals[j].name);
if( ++k == 7)
{
k = 0;
putchar( '\n');
}
}
if( k)
putchar('\n');
}
}
}
void delete( afile, flag)
char *afile;
{
int i;
#if LOWERFILE
downcase( afile);
#endif
for( i = 0; i != findex; i++)
{
register f_table huge *p = &files[ i];
if( ! strcmp( p->name, afile))
{
int j;
lword k;
long off;
char huge *tmp;
if( findex == 1)
{
p_space = space;
findex = gindex = 0;
}
else
{
register f_table huge *q;
k = p->bytes;
off = p->seek;
tmp = add_offset( space, off);
if( i + 1 < findex) /* Collapse hole */
bcopy( tmp + k, tmp, cbytes - off - k);
p_space -= k;
for( q = p, j = 0; j != findex; q++, j++) /* Adjust seek adr */
if( q->seek > off)
q->seek -= k;
if( i < --findex) /* Remove from file table */
bcopy( (byte huge *) p + sizeof( f_table), p,
(long) (findex - i) * sizeof( f_table));
for( k = j = 0; j != gindex; j++) /* Adjust index in globals */
{
register g_table *p = &globals[ j];
if( p->index == i)
{
if( ! k++)
off = j;
}
else
if( p->index > i)
p->index--;
}
if( k + off < gindex)
bcopy( add_offset( globals, off + k),
add_offset( globals, off),
(long) (gindex - off) * sizeof( g_table));
gindex -= k;
}
if( laber)
fprintf( ESTREAM, "Deleted module \"%s\"\n", p->name);
return;
}
}
if( ! flag)
nserror("Object not in library", afile);
}
static char err[] = "Write to output file failed (Disk full??)";
void write_results( fd)
{
static lib_h libheader;
register byte huge *p = (byte *) &libheader;
lword gbytes, xbytes, cbytes;
ENTER("write_results");
plbyte( p, LIBMAGIC); /* sort of stupid */
pdbyte( p, DVERSION);
pdbyte( p, LIBREVISION);
plbyte( p, gbytes = (byte huge *) &globals[ gindex] - (byte huge *) globals);
plbyte( p, xbytes = (byte huge *) &files[ findex] - (byte huge *) files);
plbyte( p, cbytes = p_space - space);
#if BIGENDIAN
flip_libstructs( gindex, findex, globals, files); /* do it here again */
#endif
/* Compound this later on */
if( Fwrite( fd, sizeof( lib_h), &libheader) != sizeof( lib_h))
nferror( err);
#if ! VERSION
if( Fwrite( fd, 10L, y1) != 10L)
nferror( err);
#endif
if( Fwrite( fd, gbytes, globals) != gbytes)
nferror( err);
#if ! VERSION
if( Fwrite( fd, 10L, y2) != 10L)
nferror( err);
#endif
if( Fwrite( fd, xbytes, &files[0]) != xbytes)
nferror( err);
#if ! VERSION
if( Fwrite( fd, 10L, y3) != 10L)
nferror( err);
#endif
if( Fwrite( fd, cbytes, space) != cbytes)
nferror( err);
Fclose( fd);
LEAVE();
}