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

  1. /* ---------------------------------------------------------------------- */
  2. /*                   Copyright (C) 1991 by Natürlich!                     */
  3. /*                      This file is copyrighted!                         */
  4. /*                Refer to the documentation for details.                 */
  5. /* ---------------------------------------------------------------------- */
  6. #define LINKER 1
  7. #include "defines.h"
  8. #include <stdio.h>
  9. #include OSBIND
  10. #include "nasm.h"
  11. #include "debug.h"
  12. #include "ldebug.h"
  13. #include NMALLOC_H
  14. #include "object.h"
  15. #include "process.h"
  16. #include "code.h"
  17.  
  18. #if ! VERSION
  19. extern char    x1[], x2[], x3[], x4[], x5[], x6[];
  20. #endif
  21.  
  22. byte      huge *pb;
  23. e_dropped huge *pe;
  24. s_dropped huge *ps;
  25. linksymbol huge *py;
  26. i_dropped huge *pi;
  27. r_dropped huge *pr;
  28. f_dropped huge *pf;
  29. lword          magic, bytes, sbytes, ibytes, rbytes, ebytes, ybytes, fbytes;
  30. lword          ysize;         /* hack for backwards compatibility */
  31. static obj_h   l;
  32.  
  33. word           version,
  34.                alignment;
  35. #if ! VERSION
  36. static word    revision;
  37. #endif
  38. static void    fix_version(), fix_sizes();
  39. #if ! DISASM
  40. extern int     relocatable,
  41.                bootable,
  42.                verbose,
  43.                pageflag;
  44. extern word    diff, head_off, endpc, origin, mv_offset;
  45.  
  46. extern byte huge  *ptohead;
  47.  
  48. #endif
  49. char    trc_loss[] = "File is truncated";
  50.  
  51.  
  52. #if VERSION
  53. # define the_10seek( x, y)
  54. #else
  55.  
  56. void the_10seek( fd, x)
  57. char  *x;
  58. {
  59.    unsigned long   foo;
  60.    static char     chkbuf[11];
  61.  
  62.    if( (foo = Fread( fd, 10L, chkbuf)) < 10L)
  63.    {
  64.       fprintf( stderr, "FOO = %ld\n", foo);
  65.       ngferror( foo, trc_loss);
  66.    }
  67.    if( strcmp( chkbuf, x))
  68.       nferror("Not a good object file");
  69. }
  70. #endif
  71.  
  72. void  do_load( fd)
  73. {
  74.    long  foo;
  75.  
  76.    ENTER("do_load");
  77.    INTEGRITY_CHECK();
  78.    if( Fread( fd, sizeof( obj_h), &l) != sizeof( obj_h))
  79.       nferror("File is too short to be an object file");
  80.    IMESS("Sizeof( obj_h) = %ld", sizeof( obj_h), 4);
  81.    magic    = lbeek( &l.magic);
  82.    version  = dbeek( &l.version);
  83. #if ! VERSION
  84.    revision = dbeek( &l.revision);
  85. #endif
  86.    alignment= dbeek( &l.alignment);
  87.    bytes    = (lword) dbeek( &l.codesize);
  88.    sbytes   = lbeek( &l.segsize);
  89.    ibytes   = lbeek( &l.immsize);
  90.    rbytes   = lbeek( &l.relsize);
  91.    ebytes   = lbeek( &l.expsize);
  92.    ybytes   = ysize = lbeek( &l.symsize);
  93.    fbytes   = lbeek( &l.fixsize);
  94.    if( magic != OBJMAGIC)
  95.       nferror("This is not an object file");
  96.    if( version < (word) OBJ_READ_COMP)
  97.       nferror("Object file was created with an obsolete version");
  98.    if( version > DVERSION)
  99.       nferror("I am too oldfashioned to understand this object format");
  100. #if ! VERSION
  101.    if( revision != ASMREVISION)
  102.       nferror("Object was created by a different revision");
  103. #endif
  104.    if( version != DVERSION)
  105.       fix_sizes( version);
  106.  
  107. #if ! DISASM
  108.    if( __p - __program + bytes >= MAXMODULE)
  109.       nferror("Objects overflow the program buffer");
  110. #endif
  111.    MESS("[ 0] --- Fread ---");
  112.    pb = nmalloc( bytes);
  113.    if( (foo = Fread( fd, bytes, pb)) != bytes)
  114.       ngferror( foo, trc_loss);
  115.  
  116.    MESS("[ 1] --- Fseek ---");
  117.    the_10seek( fd, x1);
  118.    INTEGRITY_CHECK();
  119.    MESS("[ 2] --- Sbytes ---");
  120.    if( sbytes)
  121.    {
  122.       ps = nmalloc( sbytes);
  123.       if( (foo = Fread( fd, sbytes, ps)) != sbytes)
  124.          ngferror( foo, trc_loss);
  125.    }
  126.  
  127.    MESS("[ 3] --- Fseek ---");
  128.    INTEGRITY_CHECK();
  129.    the_10seek( fd, x2);
  130.    MESS("[ 4] --- Ibytes ---");
  131.    if( ibytes)
  132.    {
  133.       pi = nmalloc( ibytes);
  134.       if( (foo = Fread( fd, ibytes, pi)) != ibytes)
  135.          ngferror( foo, trc_loss);
  136.    }
  137.  
  138.    MESS("[ 5] --- Fseek ---");
  139.    INTEGRITY_CHECK();
  140.    the_10seek( fd, x3);
  141.    MESS("[ 6] --- Rbytes ---");
  142.    if( rbytes)
  143.    {
  144.       pr = nmalloc( rbytes);
  145.       if( (foo = Fread( fd, rbytes, pr)) != rbytes)
  146.          ngferror( foo, trc_loss);
  147.    }
  148.  
  149.    MESS("[ 7] --- Fseek ---");
  150.    INTEGRITY_CHECK();
  151.    the_10seek( fd, x4);
  152.    MESS("[ 8] --- Ebytes ---");
  153.    if( ebytes)
  154.    {
  155.       pe = nmalloc( ebytes);
  156.       if( (foo = Fread( fd, ebytes, pe)) != ebytes)
  157.          ngferror( foo, trc_loss);
  158.    }
  159.  
  160.    MESS("[ 9] --- Fseek ---");
  161.    the_10seek( fd, x5);
  162.    MESS("[10] --- Ybytes ---");
  163.    if( ybytes)
  164.    {
  165.       py = nmalloc( ysize);
  166.       if( (foo = Fread( fd, ybytes, py)) != ybytes)
  167.          ngferror( foo, trc_loss);
  168.    }
  169.  
  170.    the_10seek( fd, x6);
  171.    INTEGRITY_CHECK();
  172.    MESS("[11] --- Fbytes ---");
  173.    if( fbytes)
  174.    {
  175.       pf = nmalloc( fbytes);
  176.       if( (foo = Fread( fd, fbytes, pf)) != fbytes)
  177.          ngferror( foo, trc_loss);
  178.    }
  179.  
  180.    ADD_WATCH( &pb, sizeof( char *), "pb");
  181.    ADD_WATCH( &pe, sizeof( char *), "pe");
  182.    ADD_WATCH( &ps, sizeof( char *), "ps");
  183.    ADD_WATCH( &py, sizeof( char *), "py");      
  184.    ADD_WATCH( &pi, sizeof( char *), "pi");
  185.    ADD_WATCH( &pr, sizeof( char *), "pr");
  186.    ADD_WATCH( &pf, sizeof( char *), "pf");
  187.  
  188.    if( version != DVERSION)
  189.    {
  190.       fix_version( version);        /* fix up old style object files */
  191.    }
  192.  
  193.    ybytes /= sizeof( linksymbol);
  194.    ebytes /= sizeof( e_dropped);
  195.    sbytes /= sizeof( s_dropped);
  196.    ibytes /= sizeof( i_dropped);
  197.    rbytes /= sizeof( r_dropped);
  198.    fbytes /= sizeof( f_dropped);
  199.  
  200.  
  201.    INTEGRITY_CHECK();
  202. # if BIGENDIAN
  203.    flipstructs();
  204. # endif
  205.    INTEGRITY_CHECK();
  206. #if ! DISASM
  207.    {
  208.       word  oldpc,
  209.             val = 0;
  210.  
  211.       diff  = __pc - DEFORG + mv_offset;
  212.       oldpc = __pc;
  213.       if( alignment)
  214.          if( ! pageflag && relocatable)
  215.             nferror("Conflict between -m option and requested alignment");
  216.          else
  217.             if( val = __pc & alignment)
  218.             {
  219.                dpoke( ptohead, __pc - 1);
  220.                __pc += (val = (~val & alignment) + 1);
  221.                diff += val;
  222.                if( bootable)
  223.                {
  224.                   register int   i;
  225.  
  226.                   for( i = val; i; i--)
  227.                      *__p++ = 0;
  228.                }
  229.                else
  230.                {
  231.                   dpoke( __p, __pc);
  232.                   _advance( 4);
  233.                   ptohead = __p - 2;
  234.                }
  235.             }
  236.       endpc = DEFORG;
  237.  
  238.       INTEGRITY_CHECK();
  239.       seg_link();
  240.       INTEGRITY_CHECK();
  241.       MESS("code_reloc");
  242.       code_reloc();
  243.       INTEGRITY_CHECK();
  244.       MESS("imm_link");
  245.       imm_link();
  246.       INTEGRITY_CHECK();
  247.       MESS("ref_link");
  248.       ref_link();
  249.       INTEGRITY_CHECK();
  250.       MESS("exp_link");
  251.       exp_link();
  252.       INTEGRITY_CHECK();
  253.       MESS("sym_link");
  254.       sym_link();
  255.       INTEGRITY_CHECK();
  256.       MESS("sym2_link");
  257.       sym2_link();
  258.       INTEGRITY_CHECK();
  259.       DEL_WATCH( &pb);
  260.       DEL_WATCH( &pe);
  261.       DEL_WATCH( &ps);
  262.       DEL_WATCH( &py);
  263.       DEL_WATCH( &pi);
  264.       DEL_WATCH( &pr);
  265.       DEL_WATCH( &pf);
  266.       wrapup();
  267.  
  268.       if( verbose)
  269.          if( alignment)
  270.             printf("Start: $%04X  Size:%5ld bytes  Alignment loss: %3d bytes\n",
  271.                      oldpc, (lword) __pc - oldpc, val);
  272.          else
  273.             printf("Start: $%04X  Size:%5ld bytes\n", oldpc, bytes);
  274.  
  275.    }
  276. #endif
  277.    LEAVE();
  278. }
  279.  
  280. #if BIGENDIAN
  281. void  flipstructs()
  282. {
  283.    register word huge   *q;
  284.    register lword       i;
  285.    {
  286.       register linksymbol huge *p;
  287.  
  288.       for( p = py, i = ybytes; i--; p++)
  289.       {
  290.          q  = (word huge *) p;
  291.          dswap( q); q++;
  292.          dswap( q); q++;
  293.          dswap( q); q += 2;
  294.          lswap( q);
  295.          POINTER_CHECK( q);
  296.       }
  297.    }
  298.    {
  299.       for( q = (word huge *) pe, i = ebytes; i--;)
  300.       {
  301.          dswap( q); q++;      /* val      */
  302.          dswap( q); q++;      /* aux      */
  303.          dswap( q);           /* label    */
  304.          q += 2;              /* op & fix */
  305.          dswap( q); q++;      /* t        */
  306.          dswap( q); q++;      /* l        */
  307.          POINTER_CHECK( q);
  308.          dswap( q); q++;      /* r        */
  309.       }
  310.    }
  311.    {
  312.       for( q = (word huge *) pi, i = ibytes; i--;)
  313.       {
  314.          dswap( q); q++;      /* block */
  315.          dswap( q); q++;      /* type  */
  316.          dswap( q); q++;      /* offset*/
  317.          POINTER_CHECK( q);
  318.          dswap( q); q++;      /* val   */
  319.       }
  320.    }
  321.    {
  322.       for( q = (word huge *) ps, i = sbytes; i--;)
  323.       {
  324.          dswap( q); q++;      /* type  */
  325.          dswap( q); q++;      /* index */
  326.          POINTER_CHECK( q);
  327.          dswap( q); q++;      /* size  */
  328.       }
  329.    }
  330.    {
  331.       for( q = (word huge *) pf, i = fbytes; i--;)
  332.       {
  333.          dswap( q); q++;         /* poof  */
  334.          dswap( q); q++;         /* imm   */
  335.          POINTER_CHECK( q);
  336.          dswap( q); q++;         /* index */
  337.       }
  338.    }
  339.    {
  340.       register r_dropped huge  *p;
  341.  
  342.       for( p = pr, i = rbytes; i--; p++)
  343.       {
  344.          dswap( p);
  345.          POINTER_CHECK( p);
  346.       }
  347.    }
  348. }
  349. #endif
  350.  
  351. #if VERSION == 2 || VERSION == 0
  352. # define V1_SIGNIFICANT 8
  353. # define V1_SIGNDIFF    (SIGNIFICANT - V1_SIGNIFICANT)
  354. # define V1_L_DIFF      (V1_SIGNDIFF + sizeof( word))
  355. # define V1_SIZE        (sizeof( linksymbol) - V1_L_DIFF)
  356. #endif
  357.  
  358. static void    fix_sizes( version)
  359. {
  360.    switch( version)
  361.    {
  362. #if VERSION == 2 || VERSION == 0   
  363.       case 1 :
  364.          ysize = ybytes / V1_SIZE * sizeof( linksymbol);
  365.          break;
  366. #endif
  367.       default  :
  368.          nferror( "Sorry, but that's an object file version I can't cope with");
  369.    }
  370. }
  371.  
  372.  
  373. static void    fix_version( version)
  374. {
  375.    switch( version)
  376.    {
  377. #if VERSION == 2 || VERSION == 0
  378.       case 1 :
  379.       {
  380.          word       huge      *p;
  381.          linksymbol huge      *q;
  382.          register word        i, j;
  383.          register char huge   *dst;
  384.  
  385.          i = ybytes /= V1_SIZE;           /* calc # symbols */
  386.          q = &py[ i];                     /* move to end of */
  387.          p = (word huge *) ((char huge *) q - i * V1_L_DIFF);
  388.  
  389.          while( --q, i--)
  390.          {
  391.             for( dst = &q->name[ j = SIGNIFICANT]; j-- > V1_SIGNIFICANT;)
  392.                *--dst = 0;
  393. # if PHILOSOPHICAL_PROBLEM
  394.             do
  395.             {
  396.                p = (word huge *) ((char huge *) p - 1);
  397.                *--dst = *p;
  398.             }
  399.             while( j--);
  400.             p -= sizeof( lword) / sizeof( word);
  401.             q->refs = (ref huge *) *(lword huge *)p;
  402. # else
  403.             do
  404.                *--dst = *--(char huge *)p;
  405.             while( j--);
  406.             q->refs = (ref huge *) *(--(lword huge *)p);
  407. # endif
  408.             q->type = *--p;
  409.             q->no   = *--p;
  410.             q->val  = *--p;
  411.             POINTER_CHECK( p);
  412.             POINTER_CHECK( q);
  413.          }
  414.          ybytes *= sizeof( linksymbol);
  415.          break;
  416.       }
  417. #endif
  418.  
  419.       default  :
  420.          nferror( "Sorry, but that's an object file version I can't cope with");
  421.    }
  422. }
  423.  
  424.  
  425.