
/*--------------------------------------------------------------------*/
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*                                                                    */
/*--------------------------------------------------------------------*/

#include "os2def.h"

#ifndef WORD
  typedef USHORT  WORD;
  typedef ULONG   DWORD;
#endif

#include "stdio.h"

#define EXE386 1
#include "newexe.h"
#include "exe386.h"

#include "abscons.h"
#include "abstype.h"

#include "abspro.h"
#include "absextn.h"

ULONG main(ULONG argc, PUCHAR *argv, PUCHAR envp)
{
  ULONG         i;
  ULONG         rc;
  PMODINFO      pMI, pMIPrev;

  ULONG         BaseAddr;

  PageSize    = 4096;
  OutFilePos  = 0;
  FlatSel     = 0x0158;

  /*------------------------------------------*/
  /*                                          */
  /*------------------------------------------*/
  if ( argc < 4  || !atolx( argv[argc-1], &BaseAddr) )
  {
    errmsg( ERR_BAD_ARGS, SRCFILE, LINENO, NULL );

    printf( "\n");
    printf( "ABSLDR - Create absolute binary image from EXE/DLL files\n");
    printf( "Usage:\n");
    printf( "    absldr <path\\infile_1>...<path\\infile_n> <path\\outfile> BaseAddr\n");
    printf( "Example:\n");
    printf( "    absldr absldr.exe test.img 40000\n");

    goto Main_Exit;
  }

  pMIPrev = 0;

  /*-----------------------------------------------------*/
  /* For each input .EXE/.DLL specified create a Module  */
  /* Info structure.                                     */
  /*-----------------------------------------------------*/
  for ( i=1; i < argc-2; i++ )
  {
    pMI = (PMODINFO) malloc(sizeof(MODINFO));
    memset((PVOID) pMI, 0, sizeof(MODINFO));

    if ( !pMIPrev )
    {
      pModAnchor = pMI;
      pMI->ModBaseAddr = BaseAddr;
    }
    else
    {
      pMIPrev->pModNext = pMI;
    }

    pMI->pModName    = argv[i];

    /*----------------------------------------------------*/
    /* Open each module and read the Header/Loader/Fixup  */
    /* sections of the module into an allocated buffer    */
    /* and attach this to the MI structure.               */
    /*----------------------------------------------------*/
    if ( (rc=OpenLXExe( pMI )) )
    {
      goto Main_Exit;
    }

    pMIPrev = pMI;
  }

  /*-------------------------------------------------*/
  /* Create the Output Image file.                   */
  /*                                                 */
  /* I hope the user wasn't attached to the previous */
  /* contents 'cause they're gone now!               */
  /*-------------------------------------------------*/
  if ( OpenOutFile( argv[argc-2] ) )
  {
    rc = errmsg( ERR_BAD_OUTFILE, SRCFILE, LINENO, pOutFileName );
    goto Main_Exit;
  }

  /*-------------------------------------------------------*/
  /* Pass 1                                                */
  /*                                                       */
  /* Expand each object in the .EXE/.DLL files indicated   */
  /* and output the expanded image. The File Position      */
  /* and Virtual Address of each expanded object/page are  */
  /* retained for use in Pass 2.                           */
  /*-------------------------------------------------------*/
  pMI     = pModAnchor;
  pMIPrev = 0;

  while ( pMI )
  {
    /*--------------------*/
    /* Ready for Pass 1   */
    /*--------------------*/
    if ( (rc = Pass1( pMI )) )
    {
      goto Main_Exit;
    }

    pMIPrev = pMI;

    /*----------------------------------------------------------*/
    /* Set the BaseAddress of the next module in the load image */
    /* to follow the previous module.                           */
    /*----------------------------------------------------------*/
    if ((pMI=pMI->pModNext))
    {
      pMI->ModBaseAddr = pMIPrev->ModCurAddr;
    }
  }

  /*------------------------------------------------*/
  /* Pass 2                                         */
  /*                                                */
  /* Process the Fixup Page table for each module   */
  /* and apply the fixups to the Output Image File. */
  /*------------------------------------------------*/
  pMI = pModAnchor;

  while ( pMI )
  {
    printf( "ABSLDR: Processing file: %s at %08lx\n",
            pMI->pModName,
            pMI->ModBaseAddr );

    if ( (rc = Pass2( pMI )) )
    {
      goto Main_Exit;
    }

    pMI = pMI->pModNext;
  }

Main_Exit:
  return ( rc );

}

ULONG atolx( PBYTE s, PULONG v )
{
  ULONG         i;
  UCHAR         c;

  *v = 0;

  for ( i=0; i<8; i++, s++ )
  {
    c = toupper(*s);

    if ( c >= 'A' && c <= 'F' )
    {
      *v= (*v << 4) + c-'A'+10;
    }
    else if ( c >= '0' && c <= '9' )
    {
      *v = (*v << 4) + c-'0';
    }
    else
    {
      break;
    }
  }
  return ( i );
}
