home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / nasm20b / nasm_src / libwork.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  17KB  |  671 lines

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1991 by Natürlich!                     */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. #define LIBRARIAN 1
  7. #define __BIG_GENERATOR__
  8. #include "defines.h"
  9. #include "nasm.h"
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "debug.h"
  13. #include "object.h"
  14. #include "lib.h"
  15. #if OS != TOS
  16. # include <time.h>
  17. # if OS == UNIX
  18. #  include <sys/time.h>
  19. # endif
  20. #endif
  21. #include OSBIND
  22. #include NMALLOC_H
  23. #include "code.h"
  24.  
  25. #include "ldebug.h"
  26.  
  27.  
  28. #if ! VERSION
  29. extern char    x1[], x2[], x3[], x4[], x5[], x6[];
  30. char           y1[] = " _GLOBALS ",
  31.                y2[] = " _F_INDEX ",
  32.                y3[] = " _OBJFILE ";
  33. #endif
  34.  
  35. byte huge      *__program, huge *__p, huge *ptohead;
  36. byte           __c;
  37. word           __pc, __x;
  38. lword          __lx;
  39. static char    trc_loss[] = "File is truncated";
  40.  
  41. static linksymbol huge  *py;
  42. static obj_h            l;
  43. static char huge        *space;
  44. static char huge        *p_space, huge *old_p_space;
  45.  
  46. int               version;
  47. #if ! VERSION
  48. int               revision;
  49. #endif
  50. word              gindex, findex;
  51. static lword      bytes, sbytes, ibytes, rbytes, ebytes, ybytes, fbytes;
  52. static lword      magic, gbytes, xbytes, cbytes, size, tbytes;
  53. static lword      gsize;
  54. g_table           globals[ MAXGLOBALS];
  55. f_table           files[ MAXFILES];
  56. extern char       *currfile;
  57. extern int        laber;
  58.  
  59. extern void       fix_lversion(), fix_lsizes();
  60. #if BIGENDIAN
  61. extern void       flip_libstructs();
  62. #endif
  63.  
  64. #if VERSION
  65. # undef LIBMAX
  66. # define LIBMAX 0x4000L
  67. #endif
  68.  
  69. #define SPARE  0x8000L
  70.  
  71. void pro_init()
  72. {
  73.    extern char    outofmem[];
  74.  
  75. #if OS == TOS
  76.    if( (size = (long) Malloc( -1L)) < SPARE)
  77.       nferror("Space dangerously low *ouch* in here, aborting...");
  78.    p_space = space = nmalloc( size -= SPARE); /* leave 32K for symbols */
  79. #else
  80. # if OS == UNIX || OS == AMIGA
  81.    p_space = space = nmalloc( size = LIBMAX);   /* ARGH! */
  82. # else
  83. #  if OS == MSDOS
  84.    if( ! (p_space = space = nmalloc( size = LIBMAX)))
  85.       nferror( outofmem);
  86. #  else
  87. #   error "missing code for your machinery"
  88. #  endif
  89. # endif
  90. #endif
  91.    if( laber)
  92.       fprintf( ESTREAM, "%ld bytes space allocated for modules\n", size);
  93. }
  94.  
  95. void pro_exit()
  96. {
  97. }
  98.  
  99. #if VERSION
  100. #define thel10seek( x, y)
  101. #else
  102. void thel10seek( i, x)
  103. char  *x;
  104. {
  105.    unsigned long   foo;
  106.    static char     chkbuf[11];
  107.  
  108.    if( (foo = Fread( i, 10L, chkbuf)) < 10)
  109.       ngferror( foo, trc_loss);
  110.    if( strcmp( chkbuf, x))
  111.       nferror("Not a good NASM library file");
  112.    bcopy( chkbuf, p_space, 10L);
  113.    p_space += 10;
  114. }
  115. #endif
  116.  
  117. int lload( afile)
  118. char  *afile;                     /* 3 'V's: Van Halen, VfL und Veltins! */
  119. {
  120.    static lib_h   l;
  121.    register long  foo;
  122.    int            fd;
  123.  
  124.    ENTER("lload");
  125. #if LOWERFILE
  126.    downcase( afile);
  127. #endif
  128.    IMESS( "Trying to open \"%s\" ", (long) afile, 4);
  129.    if( (fd = (int) Fopen( afile, 0)) < 0)
  130.    {
  131.       if( fd == -35)
  132.          nferror("Out of GEMDOS file handles (that's strange..) ?");
  133.       return( 0);
  134.    }
  135.    if( Fread( fd, sizeof( lib_h), &l) != sizeof( lib_h))
  136.       nferror("File is too short to be a library");
  137.    IMESS("Sizeof( lib_h) = %ld", (long) sizeof( lib_h), 4);
  138.  
  139.    magic    = lbeek( &l.magic);
  140.    version  = dbeek( &l.version);
  141. #if ! VERSION
  142.    revision = dbeek( &l.revision);
  143. #endif
  144.    gbytes   = gsize = lbeek( &l.gbytes);
  145.    xbytes   = lbeek( &l.xbytes);
  146.    cbytes   = lbeek( &l.cbytes);
  147.  
  148.    if( magic != LIBMAGIC)
  149.       nferror("This is not a library");
  150. #if BIGENDIAN
  151.    if( version < DVERSION)
  152. #else
  153.    if( version < LIB_READ_COMP)
  154. #endif
  155.       nferror("Library was created with an obsolete version");
  156.    if( version > DVERSION)
  157.       nferror("Librarian is too oldfashioned to understand object format");
  158. #if ! VERSION
  159.    if( revision != LIBREVISION)
  160.       nferror("Library revision differs");
  161. #endif
  162.    if( version != DVERSION)
  163.       fix_lsizes( version, &gsize);
  164.  
  165.    thel10seek( fd, y1);
  166.    if( (foo = Fread( fd, gbytes, globals)) != gbytes)
  167.       ngferror( foo, trc_loss);
  168.  
  169.    thel10seek( fd, y2);
  170.    if( xbytes)
  171.       if( (foo = Fread( fd, xbytes, &files[0])) != xbytes)
  172.     ngferror( foo, trc_loss);
  173.  
  174.    thel10seek( fd, y3);
  175.    if( cbytes)
  176.    {
  177.       if( (foo = Fread( fd, cbytes, space)) != cbytes)
  178.          ngferror( foo, trc_loss);
  179.       p_space += cbytes;
  180.    }
  181.    else
  182.       p_space = space;
  183.  
  184.    Fclose( fd);
  185.  
  186.    if( version != DVERSION)
  187.       fix_lversion( version, &gbytes, globals);
  188.  
  189.    gindex = (word) (gbytes / sizeof( g_table));
  190.    findex = (word) (xbytes / sizeof( f_table));
  191.  
  192. #if BIGENDIAN
  193.    flip_libstructs( gindex, findex, globals, files);
  194. #endif
  195.    if( laber)
  196.       fprintf( ESTREAM, "Read in %s: %d modules with %d globals \
  197. worth %ld bytes total\n", afile, findex, gindex, cbytes);
  198.    LEAVE();
  199.    return(1);
  200. }
  201.  
  202. void wrapup()
  203. {
  204.    nfree( py);
  205. }
  206.  
  207.  
  208. void file_lib( currfile)
  209. char  *currfile;
  210. {
  211.    register char huge      *src,
  212.                  huge      *dst;
  213.    register int            i = FSIGNIFICANT;
  214.    register f_table huge   *p = &files[ findex++];
  215.  
  216.    ENTER("file_lib");
  217.    src = get_filename( currfile);
  218.    dst = p->name;
  219.    while( (*dst++ = *src++) && i--);
  220.    while( i--)
  221.       *dst++ = 0;
  222.    if( laber)
  223.       fprintf( ESTREAM, "Put %.32s into library [%ld bytes]\n",
  224.                            currfile, tbytes);
  225.    p->seek  = old_p_space - space;
  226. #if OS == TOS
  227.    p->time  = Tgettime();
  228.    p->date  = Tgetdate();
  229. #else
  230. # if OS == MSDOS
  231.    {
  232.       struct time  watch;
  233.       struct date  calendar;
  234.  
  235.       gettime( &watch);
  236.       getdate( &calendar);
  237.       p->time = ((unsigned) watch.ti_sec >> 1) |
  238.                 ((unsigned) watch.ti_min << 5) |
  239.                 ((unsigned) watch.ti_hour << 11);
  240.       p->date = ((unsigned) calendar.da_year - 1980 << 9) |
  241.                 ((unsigned) calendar.da_mon - 1 << 5) |
  242.                 ((unsigned) calendar.da_day - 1);
  243.    }
  244. # else
  245.    {
  246.       struct tm   *watch;
  247.       time_t      the_time;
  248.  
  249.       if( (the_time = time( NULL)) == -1)
  250.          nferror("Your system rudely refuses to give the current time");
  251.  
  252.       watch = localtime( &the_time);
  253.       p->time = ((unsigned) watch->tm_sec >> 1) |
  254.                 ((unsigned) watch->tm_min << 5) |
  255.                 ((unsigned) watch->tm_hour << 11);
  256.       p->date = ((unsigned) watch->tm_year - 1900 << 9) |
  257.                 ((unsigned) watch->tm_mon << 5) |
  258.                 watch->tm_mday;
  259.    }
  260. # endif
  261. #endif
  262.    p->bytes = tbytes;
  263.    LEAVE();
  264. }
  265.  
  266.  
  267. int check_double( name)
  268. register char  *name;
  269. {
  270.    register char huge      *s;
  271.    register g_table huge   *p = &globals[0];
  272.    register int            i = gindex, j;
  273.    static char             buf[ SIGNIFICANT + 1];
  274.  
  275.    while( i--)
  276.    {
  277.       s = p++->name;
  278.       j = 0;
  279.       while( *s++ == name[j++] && j < SIGNIFICANT);
  280.       if( j >= SIGNIFICANT)
  281.       {
  282.          for( j = 0; j != SIGNIFICANT; buf[j++] = name[j]);
  283.          buf[ SIGNIFICANT] = 0;
  284.          nserror( "Symbol is already in the library", buf);
  285.          return( 1);
  286.       }
  287.    }
  288.    return(0);
  289. }
  290.  
  291.  
  292. void sym_lib()
  293. {
  294.    register linksymbol huge   *p = py;
  295.    register char huge         *dst,
  296.                  huge         *src;
  297.    register word              i  = (word) ybytes;
  298.    int                        entered = 0;
  299.  
  300.    ENTER("sym_lib");
  301.    while( i--)
  302.    {
  303.       if( ! p->refs && ! check_double( p->name))
  304.       {
  305.          if( gindex >= MAXGLOBALS)
  306.             nferror("Sorry, global symbol table space exhausted");
  307.          dst = globals[ gindex].name;
  308.          src = p->name;
  309. #if SIGNIFICANT == 8
  310.          *dst++ = *src++;     /* SIGNIFICANT == 8 */
  311.          *dst++ = *src++;
  312.          *dst++ = *src++;
  313.          *dst++ = *src++;
  314.          *dst++ = *src++;
  315.          *dst++ = *src++;
  316.          *dst++ = *src++;     /* eliminated one copy here */
  317.          *dst   = *src;
  318. #else
  319.          {
  320.             register int   j = SIGNIFICANT;
  321.  
  322.             while( j--)
  323.                *dst++ = *src++;
  324.          }
  325. #endif
  326.          entered++;
  327.          globals[ gindex++].index = findex;
  328.       }
  329.       p++;
  330.    }
  331.    if( ! entered)
  332.       nferror("Module's unusuable 'coz there's no global label w/value");
  333.    LEAVE();
  334. }
  335.  
  336. #if VERSION
  337. # define S10EEKS  0
  338. #else
  339. # define S10EEKS  6 * 10L
  340. #endif
  341.  
  342. void oload( afile)
  343. char  *afile;                     /* 3 'V's: Van Halen, VfL und Veltins! */
  344. {
  345.    register char  *x;
  346.    register long  foo;
  347.    int   i;
  348.  
  349.    ENTER("oload");
  350. #if LOWERFILE
  351.    downcase( afile);
  352. #endif
  353.    IMESS( "Trying to open \"%s\" ", (long) afile, 4);
  354.    if( (i = (int) Fopen( afile, 0)) < 0)
  355.    {
  356.       MESS("Open failed");
  357.       strcpy( x = nmalloc( strlen( afile) + 5L), afile);
  358.       complete( x, ".o65", 1);
  359.       afile = x;
  360.       if( (i = (int) Fopen( x, 0)) < 0)
  361.       {
  362.          if( i == -35)
  363.             nferror("Out of GEMDOS file handles (that's strange..) ?");
  364.          nferror( "Object file does not exist");
  365.       }
  366.    }
  367.    if( Fread( i, sizeof( obj_h), &l) != sizeof( obj_h))
  368.       nferror("File is too short to be an object file");
  369.    IMESS("Sizeof( obj_h) = %ld", (long) sizeof( obj_h), 4);
  370.  
  371.    magic    = lbeek( &l.magic);
  372.    version  = dbeek( &l.version);
  373. #if ! VERSION
  374.    revision = dbeek( &l.revision);
  375. #endif
  376.    bytes    = (lword) dbeek( &l.codesize);
  377.    sbytes   = lbeek( &l.segsize);
  378.    ibytes   = lbeek( &l.immsize);
  379.    rbytes   = lbeek( &l.relsize);
  380.    ebytes   = lbeek( &l.expsize);
  381.    ybytes   = lbeek( &l.symsize);
  382.    fbytes   = lbeek( &l.fixsize);
  383.  
  384.    if( magic != OBJMAGIC)
  385.       nferror("This is not an object file");
  386.    if( version < DVERSION)
  387.       nferror("Object file was created with an obsolete version");
  388.    if( version > DVERSION)
  389.       nferror("Librarian is to oldfashioned to understand this object format");
  390. #if ! VERSION
  391.    if( revision != ASMREVISION)
  392.       nferror("Object file was made under old revision");
  393. #endif
  394.    if( ! ybytes)
  395.       nwarning("Object file contains no global symbols");
  396.    tbytes = sbytes + ibytes + rbytes + ebytes + ybytes + fbytes + S10EEKS +
  397.             bytes + sizeof( obj_h);
  398.    if( ((old_p_space = p_space) - space) + tbytes > size)
  399.       nferror("Can't fit all these files into memory");
  400.  
  401.    bcopy( &l, p_space, (long) sizeof( obj_h));
  402.    p_space += sizeof( obj_h);
  403.  
  404.    if( (foo = Fread( i, bytes, p_space)) != bytes)
  405.       ngferror( foo, trc_loss);
  406.    p_space += bytes;
  407.  
  408.    thel10seek( i, x1);
  409.    if( sbytes)
  410.    {
  411.       if( (foo = Fread( i, sbytes, p_space)) != sbytes)
  412.          ngferror( foo, trc_loss);
  413.       p_space += sbytes;
  414.    }
  415.  
  416.    thel10seek( i, x2);
  417.    if( ibytes)
  418.    {
  419.       if( (foo = Fread( i, ibytes, p_space)) != ibytes)
  420.          ngferror( foo, trc_loss);
  421.       p_space += ibytes;
  422.    }
  423.  
  424.    thel10seek( i, x3);
  425.    if( rbytes)
  426.    {
  427.       if( (foo = Fread( i, rbytes, p_space)) != rbytes)
  428.          ngferror( foo, trc_loss);
  429.       p_space += rbytes;
  430.    }
  431.  
  432.    thel10seek( i, x4);
  433.    if( ebytes)
  434.    {
  435.       if( (foo = Fread( i, ebytes, p_space)) != ebytes)
  436.          ngferror( foo, trc_loss);
  437.       p_space += ebytes;
  438.    }
  439.  
  440.    thel10seek( i, x5);
  441.    if( ybytes)
  442.    {
  443.       py = nmalloc( ybytes);
  444.       if( (foo = Fread( i, ybytes, py)) != ybytes)
  445.          ngferror( foo, trc_loss);
  446.       bcopy( py, p_space, ybytes);
  447.       p_space += ybytes;
  448.    }
  449.  
  450.    thel10seek( i, x6);
  451.    if( fbytes)
  452.    {
  453.       if( (foo = Fread( i, fbytes, p_space)) != fbytes)
  454.          ngferror( foo, trc_loss);
  455.       p_space += fbytes;
  456.    }
  457.  
  458.    ybytes /= sizeof( linksymbol);
  459. #if BIGENDIAN
  460.    fliplinks();
  461. #endif
  462.    LEAVE();
  463. }
  464.  
  465.  
  466. #if BIGENDIAN
  467. void  fliplinks()
  468. {
  469.    register lword            i;
  470.    register word huge       *q;
  471.    register linksymbol huge *p;
  472.  
  473.    for( p = py, i = ybytes; i--; p++)
  474.    {
  475.       q = (word *) p;
  476.       dswap( q);  q++;           /* val   */
  477.       dswap( q);  q++;           /* no    */
  478.       dswap( q);  q++;           /* type  */
  479.       q++;                       /* dummy */
  480.       lswap( q);                 /* refs  */
  481.       POINTER_CHECK( q);
  482.    }
  483. }
  484. #endif
  485.  
  486. void extract( afile)
  487. char  *afile;
  488. {
  489.    long  size;
  490.    int   fp, i;
  491.  
  492.    for( i = findex; i--;)
  493.       if( ! strcmp( files[i].name, afile))
  494.       {
  495.          if( (fp = (int) Fkreate( currfile = afile, 0x664)) < 0)
  496.             ngferror( fp, "Couldn't create output file");
  497.          if( Fwrite( fp, (size = files[i].bytes), space + files[ i].seek)
  498.                != size)
  499.             nferror("out of space");
  500.          Fclose( fp);
  501.          return;
  502.       }
  503.    nserror("Module unknown", afile);
  504. }
  505.  
  506. static char  *months[] =
  507. {
  508.    "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  509.    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  510. };
  511.  
  512.  
  513. void list( flag)
  514. {
  515.    int         i;
  516.    unsigned    j, k;
  517.  
  518.    printf("Modules in library:\n");
  519.    for( i = 0; i != findex; i++)
  520.    {
  521.       register f_table  *p = &files[ i];
  522.  
  523.       j = p->time;
  524.       k = p->date;
  525.       printf("%5.5ld bytes [%2.2d:%2.2d-%2.2d.%s.%d] : %-32s \n",
  526.                p->bytes,
  527.                j >> 11, (j >> 5) & 0x3F,
  528.                k & 0x1F, months[ ((k >> 5) & 0xF) - 1], 1980 + (k >> 9),
  529.                p->name);
  530.       if( flag)
  531.       {
  532.          for( k = j = 0; j != gindex; j++)
  533.             if( globals[ j].index == i)
  534.             {
  535.                if( ! k)
  536.                   putchar('\t');
  537.                printf("%-8s ", globals[j].name);
  538.                if( ++k == 7)
  539.                {
  540.                   k = 0;
  541.                   putchar( '\n');
  542.                }
  543.             }
  544.          if( k)
  545.             putchar('\n');
  546.       }
  547.    }
  548. }
  549.  
  550.  
  551. void delete( afile, flag)
  552. char  *afile;
  553. {
  554.    int   i;
  555.  
  556. #if LOWERFILE
  557.    downcase( afile);
  558. #endif
  559.    for( i = 0; i != findex; i++)
  560.    {
  561.       register f_table huge   *p = &files[ i];
  562.  
  563.       if( ! strcmp( p->name, afile))
  564.       {
  565.          int         j;
  566.          lword       k;
  567.          long        off;
  568.          char huge   *tmp;
  569.  
  570.          if( findex == 1)
  571.          {
  572.             p_space = space;
  573.             findex = gindex = 0;
  574.          }
  575.          else
  576.          {
  577.             register f_table huge *q;
  578.  
  579.             k   = p->bytes;
  580.             off = p->seek;
  581.             tmp = add_offset( space, off);
  582.  
  583.             if( i + 1 < findex)         /* Collapse hole */
  584.                bcopy( tmp + k, tmp, cbytes - off - k);
  585.             p_space -= k;
  586.  
  587.             for( q = p, j = 0; j != findex; q++, j++)  /* Adjust seek adr */
  588.                if( q->seek > off)
  589.                   q->seek -= k;
  590.  
  591.             if( i < --findex)             /* Remove from file table */
  592.                bcopy( (byte huge *) p + sizeof( f_table), p,
  593.                        (long) (findex - i) * sizeof( f_table));
  594.  
  595.             for( k = j = 0; j != gindex; j++)  /* Adjust index in globals */
  596.             {
  597.                register g_table  *p = &globals[ j];
  598.  
  599.                if( p->index == i)
  600.                {
  601.                   if( ! k++)
  602.                      off = j;
  603.                }
  604.                else
  605.                   if( p->index > i)
  606.                      p->index--;
  607.             }
  608.  
  609.             if( k + off < gindex)
  610.                bcopy( add_offset( globals, off + k),
  611.                       add_offset( globals, off),
  612.                       (long) (gindex - off) * sizeof( g_table));
  613.             gindex -= k;
  614.          }
  615.          if( laber)
  616.             fprintf( ESTREAM, "Deleted module \"%s\"\n", p->name);
  617.          return;
  618.       }
  619.    }
  620.    if( ! flag)
  621.       nserror("Object not in library", afile);
  622. }
  623.  
  624.  
  625. static char err[] = "Write to output file failed (Disk full??)";
  626.  
  627. void write_results( fd)
  628. {
  629.    static lib_h         libheader;
  630.    register byte huge   *p = (byte *) &libheader;
  631.    lword                gbytes, xbytes, cbytes;
  632.  
  633.    ENTER("write_results");
  634.    plbyte( p, LIBMAGIC);                           /* sort of stupid */
  635.    pdbyte( p, DVERSION);
  636.    pdbyte( p, LIBREVISION);
  637.    plbyte( p, gbytes = (byte huge *) &globals[ gindex] - (byte huge *) globals);
  638.    plbyte( p, xbytes = (byte huge *) &files[ findex] - (byte huge *) files);
  639.    plbyte( p, cbytes = p_space - space);
  640.  
  641. #if BIGENDIAN
  642.    flip_libstructs( gindex, findex, globals, files); /* do it here again */
  643. #endif
  644.  
  645.    /* Compound this later on */
  646.    if( Fwrite( fd, sizeof( lib_h), &libheader) != sizeof( lib_h))
  647.       nferror( err);
  648. #if ! VERSION
  649.    if( Fwrite( fd, 10L, y1) != 10L)
  650.       nferror( err);
  651. #endif
  652.    if( Fwrite( fd, gbytes, globals) != gbytes)
  653.       nferror( err);
  654. #if ! VERSION
  655.    if( Fwrite( fd, 10L, y2) != 10L)
  656.       nferror( err);
  657. #endif
  658.    if( Fwrite( fd, xbytes, &files[0]) != xbytes)
  659.       nferror( err);
  660. #if ! VERSION
  661.    if( Fwrite( fd, 10L, y3) != 10L)
  662.       nferror( err);
  663. #endif
  664.    if( Fwrite( fd, cbytes, space) != cbytes)
  665.       nferror( err);
  666.    Fclose( fd);
  667.    LEAVE();
  668. }
  669.  
  670.  
  671.