/* BFD back-end for Intel 386 COFF files (go32 variant with a stub).
   Copyright 1997, 1998, 1999 Free Software Foundation, Inc.
   Written by Robert Hoehne.

   This file is part of BFD, the Binary File Descriptor library.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */

/* This file handles now also stubbed coff images. The stub is a small
   DOS executable program before the coff image to load it in memory
   and execute it. This is needed, because DOS cannot run coff files.

   All the functions below are called by the corresponding functions
   from coffswap.h.
   The only thing what they do is to adjust the information stored in
   the COFF file which are offset into the file.
   This is needed, because DJGPP uses a very special way to load and run
   the coff image. It loads the image in memory and assumes then, that the
   image had no stub by using the filepointers as pointers in the coff
   image and NOT in the file.

   To be compatible with any existing executables I have fixed this
   here and NOT in the DJGPP startup code.
 */

#define TARGET_SYM		go32stubbedcoff_vec
#define TARGET_NAME		"coff-go32-exe"
#define TARGET_UNDERSCORE	'_'
#define COFF_GO32_EXE
#define COFF_LONG_SECTION_NAMES
#define COFF_SUPPORT_GNU_LINKONCE

#define COFF_SECTION_ALIGNMENT_ENTRIES \
{ COFF_SECTION_NAME_EXACT_MATCH (".data"), \
  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }, \
{ COFF_SECTION_NAME_EXACT_MATCH (".text"), \
  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 4 }

#include "bfd.h"

/* At first the prototypes */

static void
adjust_filehdr_in_post PARAMS ((bfd * abfd, PTR src, PTR dst));
static void
adjust_filehdr_out_pre PARAMS ((bfd * abfd, PTR in, PTR out));
static void
adjust_filehdr_out_post PARAMS ((bfd * abfd, PTR in, PTR out));

static void
adjust_scnhdr_in_post PARAMS ((bfd * abfd, PTR ext, PTR in));
static void
adjust_scnhdr_out_pre PARAMS ((bfd * abfd, PTR in, PTR out));
static void
adjust_scnhdr_out_post PARAMS ((bfd * abfd, PTR in, PTR out));

static void
adjust_aux_in_post PARAMS ((bfd * abfd, PTR ext1, int type, int class, int indx,
			    int numaux, PTR in1));
static void
adjust_aux_out_pre PARAMS ((bfd * abfd, PTR inp, int type, int class, int indx,
			    int numaux, PTR extp));
static void
adjust_aux_out_post PARAMS ((bfd * abfd, PTR inp, int type, int class, int indx,
			     int numaux, PTR extp));

static void
create_go32_stub PARAMS ((bfd * abfd));

/*
   All that ..._PRE and ...POST functions are called from the corresponding
   coff_swap... functions. The ...PRE functions are called at the beginning
   of the function and the ...POST functions at the end of the swap routines.
 */

#define COFF_ADJUST_FILEHDR_IN_POST adjust_filehdr_in_post
#define COFF_ADJUST_FILEHDR_OUT_PRE adjust_filehdr_out_pre
#define COFF_ADJUST_FILEHDR_OUT_POST adjust_filehdr_out_post

#define COFF_ADJUST_SCNHDR_IN_POST adjust_scnhdr_in_post
#define COFF_ADJUST_SCNHDR_OUT_PRE adjust_scnhdr_out_pre
#define COFF_ADJUST_SCNHDR_OUT_POST adjust_scnhdr_out_post

#define COFF_ADJUST_AUX_IN_POST adjust_aux_in_post
#define COFF_ADJUST_AUX_OUT_PRE adjust_aux_out_pre
#define COFF_ADJUST_AUX_OUT_POST adjust_aux_out_post

static boolean
  go32_stubbed_coff_bfd_copy_private_bfd_data PARAMS ((bfd * ibfd, bfd * obfd));

#define coff_bfd_copy_private_bfd_data go32_stubbed_coff_bfd_copy_private_bfd_data

#include "coff-i386.c"

/* I hold in the usrdata the stub */
#define bfd_coff_go32stub bfd_usrdata

/* This macro is used, because I cannot assume the endianess of the
   host system */
#define _H(index) (bfd_h_get_16(abfd, (bfd_byte *)(header+index*2)))

/* These bytes are a 2048-byte DOS executable, which loads the COFF
   image into memory and then runs it. It is called 'stub' */

static unsigned char stub_bytes[STUBSIZE] =
{
#include "go32stub.h"
};

/*
   I have not commented each swap function below, because the
   technique is in any function the same. For the ...in function,
   all the pointers are adjusted by adding STUBSIZE and for the
   ...out function, it is subtracted first and after calling the
   standard swap function it is reset to the old value */

/* This macro is used for adjusting the filepointers, which
   is done only, if the pointer is nonzero */

#define ADJUST_VAL(val,diff) \
  if (val != 0) val += diff

static void
adjust_filehdr_in_post  (abfd, src, dst)
     bfd *abfd;
     PTR src;
     PTR dst;
{
  FILHDR *filehdr_src = (FILHDR *) src;
  struct internal_filehdr *filehdr_dst = (struct internal_filehdr *) dst;

  ADJUST_VAL (filehdr_dst->f_symptr, STUBSIZE);

  /* Save now the stub to be used later */
  bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, STUBSIZE);

  /* Since this function returns no status, I do not set here
     any bfd_error_...
     That means, before the use of bfd_coff_go32stub (), this value
     should be checked if it is != NULL */
  if (bfd_coff_go32stub (abfd) == NULL)
    return;
  memcpy (bfd_coff_go32stub (abfd), filehdr_src->stub, STUBSIZE);
}

static void
adjust_filehdr_out_pre  (abfd, in, out)
     bfd *abfd;
     PTR in;
     PTR out;
{
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
  FILHDR *filehdr_out = (FILHDR *) out;

  /* Generate the stub */
  create_go32_stub (abfd);

  /* Copy the stub to the file header */
  if (bfd_coff_go32stub (abfd) != NULL)
    memcpy (filehdr_out->stub, bfd_coff_go32stub (abfd), STUBSIZE);
  else
    /* use the default */
    memcpy (filehdr_out->stub, stub_bytes, STUBSIZE);

  ADJUST_VAL (filehdr_in->f_symptr, -STUBSIZE);
}

static void
adjust_filehdr_out_post  (abfd, in, out)
     bfd *abfd ATTRIBUTE_UNUSED;
     PTR in;
     PTR out ATTRIBUTE_UNUSED;
{
  struct internal_filehdr *filehdr_in = (struct internal_filehdr *) in;
  /* undo the above change */
  ADJUST_VAL (filehdr_in->f_symptr, STUBSIZE);
}

static void
adjust_scnhdr_in_post  (abfd, ext, in)
     bfd *abfd ATTRIBUTE_UNUSED;
     PTR ext ATTRIBUTE_UNUSED;
     PTR in;
{
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;

  ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
  ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
  ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
}

static void
adjust_scnhdr_out_pre  (abfd, in, out)
     bfd *abfd ATTRIBUTE_UNUSED;
     PTR in;
     PTR out ATTRIBUTE_UNUSED;
{
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;

  ADJUST_VAL (scnhdr_int->s_scnptr, -STUBSIZE);
  ADJUST_VAL (scnhdr_int->s_relptr, -STUBSIZE);
  ADJUST_VAL (scnhdr_int->s_lnnoptr, -STUBSIZE);
}

static void
adjust_scnhdr_out_post (abfd, in, out)
     bfd *abfd ATTRIBUTE_UNUSED;
     PTR in;
     PTR out ATTRIBUTE_UNUSED;
{
  struct internal_scnhdr *scnhdr_int = (struct internal_scnhdr *) in;

  ADJUST_VAL (scnhdr_int->s_scnptr, STUBSIZE);
  ADJUST_VAL (scnhdr_int->s_relptr, STUBSIZE);
  ADJUST_VAL (scnhdr_int->s_lnnoptr, STUBSIZE);
}

static void
adjust_aux_in_post  (abfd, ext1, type, class, indx, numaux, in1)
     bfd *abfd ATTRIBUTE_UNUSED;
     PTR ext1 ATTRIBUTE_UNUSED;
     int type;
     int class;
     int indx ATTRIBUTE_UNUSED;
     int numaux ATTRIBUTE_UNUSED;
     PTR in1;
{
  union internal_auxent *in = (union internal_auxent *) in1;

  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
    {
      ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
    }
}

static void
adjust_aux_out_pre  (abfd, inp, type, class, indx, numaux, extp)
     bfd *abfd ATTRIBUTE_UNUSED;
     PTR inp;
     int type;
     int class;
     int indx ATTRIBUTE_UNUSED;
     int numaux ATTRIBUTE_UNUSED;
     PTR extp ATTRIBUTE_UNUSED;
{
  union internal_auxent *in = (union internal_auxent *) inp;

  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
    {
      ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, -STUBSIZE);
    }
}

static void
adjust_aux_out_post (abfd, inp, type, class, indx, numaux, extp)
     bfd *abfd ATTRIBUTE_UNUSED;
     PTR inp;
     int type;
     int class;
     int indx ATTRIBUTE_UNUSED;
     int numaux ATTRIBUTE_UNUSED;
     PTR extp ATTRIBUTE_UNUSED;
{
  union internal_auxent *in = (union internal_auxent *) inp;

  if (class == C_BLOCK || class == C_FCN || ISFCN (type) || ISTAG (class))
    {
      ADJUST_VAL (in->x_sym.x_fcnary.x_fcn.x_lnnoptr, STUBSIZE);
    }
}

/*
   That's the function, which creates the stub. There are
   different cases from where the stub is taken.
   At first the environment variable $(GO32STUB) is checked and then
   $(STUB) if it was not set.
   If it exists and points to a valid stub the stub is taken from
   that file. This file can be also a whole executable file, because
   the stub is computed from the exe information at the start of that
   file.

   If there was any error, the standard stub (compiled in this file)
   is taken.
 */

static void
create_go32_stub (abfd)
     bfd *abfd;
{
  /* Do it only once */
  if (bfd_coff_go32stub (abfd) == NULL)
    {
      char *stub;
      struct stat st;
      int f;
      unsigned char header[10];
      char magic[8];
      unsigned long coff_start, exe_start;

      /* Check at first the environment variable $(GO32STUB) */
      stub = getenv ("GO32STUB");
      /* Now check the environment variable $(STUB) */
      if (stub == NULL)
	stub = getenv ("STUB");
      if (stub == NULL)
	goto stub_end;
      if (stat (stub, &st) != 0)
	goto stub_end;
#ifdef O_BINARY
      f = open (stub, O_RDONLY | O_BINARY);
#else
      f = open (stub, O_RDONLY);
#endif
      if (f < 0)
	goto stub_end;
      if (read (f, &header, sizeof (header)) < 0)
	{
	  close (f);
	  goto stub_end;
	}
      if (_H (0) != 0x5a4d)	/* it is not an exe file */
	{
	  close (f);
	  goto stub_end;
	}
      /* Compute the size of the stub (it is every thing up
         to the beginning of the coff image) */
      coff_start = (long) _H (2) * 512L;
      if (_H (1))
	coff_start += (long) _H (1) - 512L;

      /* Currently there is only a fixed stub size of 2048 bytes
         supported */
      if (coff_start != 2048)
	{
	  close (f);
	  goto stub_end;
	}
      exe_start = _H (4) * 16;
      if ((unsigned long) lseek (f, exe_start, SEEK_SET) != exe_start)
	{
	  close (f);
	  goto stub_end;
	}
      if (read (f, &magic, 8) != 8)
	{
	  close (f);
	  goto stub_end;
	}
      if (memcmp (magic, "go32stub", 8) != 0)
	{
	  close (f);
	  goto stub_end;
	}
      /* Now we found a correct stub (hopefully) */
      bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, coff_start);
      if (bfd_coff_go32stub (abfd) == NULL)
	{
	  close (f);
	  return;
	}
      lseek (f, 0L, SEEK_SET);
      if ((unsigned long) read (f, bfd_coff_go32stub (abfd), coff_start)
	  != coff_start)
	{
	  bfd_release (abfd, bfd_coff_go32stub (abfd));
	  bfd_coff_go32stub (abfd) = NULL;
	}
      close (f);
    }
stub_end:
  /* There was something wrong above, so use now the standard builtin
     stub */
  if (bfd_coff_go32stub (abfd) == NULL)
    {
      bfd_coff_go32stub (abfd) = (PTR) bfd_alloc (abfd, STUBSIZE);
      if (bfd_coff_go32stub (abfd) == NULL)
	{
	  return;
	}

      memcpy (bfd_coff_go32stub (abfd), stub_bytes, STUBSIZE);
    }
}

/* If ibfd was a stubbed coff image, copy the stub from that bfd
   to the new obfd.
 */

static boolean
go32_stubbed_coff_bfd_copy_private_bfd_data  (ibfd, obfd)
     bfd *ibfd;
     bfd *obfd;
{
  /* check if both are the same targets */
  if (ibfd->xvec != obfd->xvec)
    return true;

  /* check if both have a valid stub */
  if (bfd_coff_go32stub (ibfd) == NULL
      || bfd_coff_go32stub (obfd) == NULL)
    return true;

  /* Now copy the stub */
  memcpy (bfd_coff_go32stub (obfd), bfd_coff_go32stub (ibfd), STUBSIZE);

  return true;
}
