home *** CD-ROM | disk | FTP | other *** search
- /* ---------------------------------------------------------------------- */
- /* 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();
- }
-
-
-