/* ---------------------------------------------------------------------- */ /* Copyright (C) 1991 by Natrlich! */ /* This file is copyrighted! */ /* Refer to the documentation for details. */ /* ---------------------------------------------------------------------- */ #define LINKER 1 #include #include "defines.h" #include OSBIND #include "nasm.h" #include "debug.h" #include "ldebug.h" #include NMALLOC_H #include "labels.h" #include "object.h" #include "code.h" #include "lib.h" #if VERSION # define the_10seek( x, y) #endif extern label huge *h_global[SEP]; extern char huge *space, huge *old_p_space, huge *p_space; extern char trc_loss[], header[]; extern int version; extern word diff, head_off, endpc; extern lword magic, __lx; extern obj_h l; extern lword bytes; #if ! VERSION static int revision; #endif extern void fix_lversion(), fix_lsizes(); #if BIGENDIAN extern void flip_libstructs(); #endif static g_table huge *globals; static f_table huge *files; word gindex, findex; static lword gbytes, fbytes, cbytes; static lword gsize, fsize; #if ! VERSION extern char x1[], x2[], x3[], x4[], x5[], x6[]; static char y1[] = " _GLOBALS ", y2[] = " _F_INDEX ", y3[] = " _OBJFILE "; #endif check_name( name) register char *name; { register char *s; register int i = gindex, j; while( i--) { s = globals[i].name; j = 0; while( name[j] && *s++ == name[j] && ++j < SIGNIFICANT); if( ! (name[j] || *s) || j == SIGNIFICANT) return( globals[i].index ); } return( -1); } void find_undef() { register int i, r; register label huge *p; ENTER("find_undef"); restart: for( i = 0; i != SEP; i++) if( p = h_global[ i]) do if( p->refs) if( (r = check_name( p->name)) != -1) { xload( files[ r].seek, (long) files[ r].bytes); goto restart; } while( p = p->next); LEAVE(); } static int fd; static char *bfile; lload( afile) char *afile; /* 3 'V's: Van Halen, VfL und Veltins! */ { static lib_h l; register char *x; register long foo; ENTER("lload"); #if LOWERFILE downcase( afile); #endif IMESS( "Trying to open \"%s\" ", (lword) afile, 4); if( (fd = (int) Fopen( afile, OPEN_R)) < 0) { MESS("Open failed"); x = (char *) nmalloc( strlen( afile) + strlen( header) + 5L); strcpy( x, header); strcat( x, afile); complete( x, ".l65", 1); afile = x; if( (fd = (int) Fopen( afile, OPEN_R)) < 0) { if( fd == -35) nferror("Out of GEMDOS file handles (that's strange..) ?)"); nferror("Library file not found"); } } bfile = afile; INTEGRITY_CHECK(); if( Fread( fd, sizeof( lib_h), &l) != sizeof( lib_h)) nferror("File is too short to be a library"); IMESS("Sizeof( lib_h) = %ld", sizeof( lib_h), 4); magic = lbeek( &l.magic); version = dbeek( &l.version); #if ! VERSION revision = dbeek( &l.revision); #endif gbytes = gsize = lbeek( &l.gbytes); fbytes = fsize = 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("Linker is too oldfashioned for these fancy new libraries"); #if ! VERSION if( revision != LIBREVISION) nferror("Library was created by a different revision"); #endif if( version != DVERSION) fix_lsizes( version, &gsize, &fsize); INTEGRITY_CHECK(); the_10seek( fd, y1); globals = (g_table *) nmalloc( gsize); if( (foo = Fread( fd, gbytes, globals)) != gbytes) ngferror( foo, trc_loss); INTEGRITY_CHECK(); the_10seek( fd, y2); files = (f_table *) nmalloc( fsize); if( fbytes) if( (foo = Fread( fd, fbytes, files)) != fbytes) ngferror( foo, trc_loss); INTEGRITY_CHECK(); the_10seek( fd, y3); if( version != DVERSION) fix_lversion( version, &gbytes, globals, &fbytes, files); gindex = (word) (gbytes / sizeof( g_table)); findex = (word) (fbytes / sizeof( f_table)); #if BIGENDIAN flip_libstructs( gindex, findex, globals, files); #endif INTEGRITY_CHECK(); find_undef(); Fclose( fd); nfree( globals); nfree( files); LEAVE(); } #if VERSION void xload( seek, bckbytes) long seek, bckbytes; { extern int verbose; ENTER("xload"); if( Fseek( seek, fd, 1) < 0) nferror("Library file corrupted"); if( verbose) printf( "%-16s ", bfile); do_load( fd); if( Fseek( - (bckbytes + seek), fd, 1) < 0) nierror("Seek failure"); LEAVE(); } #else void xload( seek, bckbytes) long seek, bckbytes; { extern int verbose; long pos; ENTER("xload"); pos = Fseek( 0, fd, 1); if( Fseek( seek, fd, 1) < 0) nferror("Library file corrupted"); if( verbose) printf( "%-16s ", bfile); do_load( fd); if( Fseek( - (bckbytes + seek), fd, 1) < 0) nierror("Seek failure"); if( Fseek( 0, fd, 1) != pos) nferror("The seek just didn't work"); LEAVE(); } #endif