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 <stdio.h>
- #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
-