/* BFD back-end for Intel 386 COFF files (DJGPP variant with a stub).
   Copyright (C) 1997-2024 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 3 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., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, 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.

   The COFF image is loaded in memory without the stub attached, so
   all offsets are relative to the beginning of the image, not the
   actual file.  We handle this in bfd by setting bfd->origin to where
   the COFF image starts.  */

#define TARGET_SYM		i386_coff_go32stubbed_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_LONG_FILENAMES

#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 }, \
{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi"), \
  COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }

/* Section contains extended relocations. */
#define IMAGE_SCN_LNK_NRELOC_OVFL (0x01000000)

#include "sysdep.h"
#include "bfd.h"
#include "coff/msdos.h"

static bfd_cleanup go32exe_check_format (bfd *);
static bool go32exe_write_object_contents (bfd *);
static bool go32exe_mkobject (bfd *);
static bool go32exe_copy_private_bfd_data (bfd *, bfd *);

/* Defined in coff-go32.c.  */
bool _bfd_go32_mkobject (bfd *);
void _bfd_go32_swap_scnhdr_in (bfd *, void *, void *);
unsigned int _bfd_go32_swap_scnhdr_out (bfd *, void *, void *);

#define COFF_CHECK_FORMAT go32exe_check_format
#define COFF_WRITE_CONTENTS go32exe_write_object_contents
#define coff_mkobject go32exe_mkobject
#define coff_bfd_copy_private_bfd_data go32exe_copy_private_bfd_data
#define coff_SWAP_scnhdr_in _bfd_go32_swap_scnhdr_in
#define coff_SWAP_scnhdr_out _bfd_go32_swap_scnhdr_out

#include "coff-i386.c"

/* This macro is used, because I cannot assume the endianness of the
   host system.  */
#define _H(index) (H_GET_16 (abfd, (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'.  */
#define GO32EXE_DEFAULT_STUB_SIZE 2048
static const unsigned char go32exe_default_stub[GO32EXE_DEFAULT_STUB_SIZE] =
{
#include "go32stub.h"
};

/* Temporary location for stub read from input file.  */
static char * go32exe_temp_stub = NULL;
static bfd_size_type go32exe_temp_stub_size = 0;

/* 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.

   Ideally this function should exec '$(TARGET)-stubify' to generate
   a stub, like gcc does.  */

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

      /* If we read a stub from an input file, use that one.  */
      if (go32exe_temp_stub != NULL)
	{
	  coff_data (abfd)->stub = bfd_alloc (abfd,
						  go32exe_temp_stub_size);
	  if (coff_data (abfd)->stub == NULL)
	    return;
	  memcpy (coff_data (abfd)->stub, go32exe_temp_stub,
		  go32exe_temp_stub_size);
	  coff_data (abfd)->stub_size = go32exe_temp_stub_size;
	  free (go32exe_temp_stub);
	  go32exe_temp_stub = NULL;
	  go32exe_temp_stub_size = 0;
	  return;
	}

      /* 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;

      exe_start = _H (4) * 16;
      if ((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 (! startswith (magic, "go32stub"))
	{
	  close (f);
	  goto stub_end;
	}
      /* Now we found a correct stub (hopefully).  */
      coff_data (abfd)->stub = bfd_alloc (abfd, (bfd_size_type) coff_start);
      if (coff_data (abfd)->stub == NULL)
	{
	  close (f);
	  return;
	}
      lseek (f, 0L, SEEK_SET);
      if ((unsigned long) read (f, coff_data (abfd)->stub, coff_start)
	  != coff_start)
	{
	  bfd_release (abfd, coff_data (abfd)->stub);
	  coff_data (abfd)->stub = NULL;
	}
      else
	coff_data (abfd)->stub_size = coff_start;
      close (f);
    }
 stub_end:
  /* There was something wrong above, so use now the standard builtin
     stub.  */
  if (coff_data (abfd)->stub == NULL)
    {
      coff_data (abfd)->stub
	= bfd_alloc (abfd, (bfd_size_type) GO32EXE_DEFAULT_STUB_SIZE);
      if (coff_data (abfd)->stub == NULL)
	return;
      memcpy (coff_data (abfd)->stub, go32exe_default_stub,
	      GO32EXE_DEFAULT_STUB_SIZE);
      coff_data (abfd)->stub_size = GO32EXE_DEFAULT_STUB_SIZE;
    }
}

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

static bool
go32exe_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  /* Check if both are the same targets.  */
  if (ibfd->xvec != obfd->xvec)
    return true;

  /* Make sure we have a source stub.  */
  BFD_ASSERT (coff_data (ibfd)->stub != NULL);

  /* Reallocate the output stub if necessary.  */
  if (coff_data (ibfd)->stub_size > coff_data (obfd)->stub_size)
    coff_data (obfd)->stub = bfd_alloc (obfd, coff_data (ibfd)->stub_size);
  if (coff_data (obfd)->stub == NULL)
    return false;

  /* Now copy the stub.  */
  memcpy (coff_data (obfd)->stub, coff_data (ibfd)->stub,
	  coff_data (ibfd)->stub_size);
  coff_data (obfd)->stub_size = coff_data (ibfd)->stub_size;
  obfd->origin = coff_data (obfd)->stub_size;

  return true;
}

/* Cleanup function, returned from check_format hook.  */

static void
go32exe_cleanup (bfd *abfd)
{
  abfd->origin = 0;
  coff_object_cleanup (abfd);

  free (go32exe_temp_stub);
  go32exe_temp_stub = NULL;
  go32exe_temp_stub_size = 0;
}

/* Check that there is a GO32 stub and read it to go32exe_temp_stub.
   Then set abfd->origin so that the COFF image is read at the correct
   file offset.  */

static bfd_cleanup
go32exe_check_format (bfd *abfd)
{
  struct external_DOS_hdr filehdr_dos;
  uint16_t num_pages;
  uint16_t last_page_size;
  uint32_t header_end;
  bfd_size_type stubsize;

  /* This format can not appear in an archive.  */
  if (abfd->origin != 0)
    {
      bfd_set_error (bfd_error_wrong_format);
      return NULL;
    }

  bfd_set_error (bfd_error_system_call);

  /* Read in the stub file header, which is a DOS MZ executable.  */
  if (bfd_read (&filehdr_dos, DOS_HDR_SIZE, abfd) != DOS_HDR_SIZE)
    goto fail;

  /* Make sure that this is an MZ executable.  */
  if (H_GET_16 (abfd, filehdr_dos.e_magic) != IMAGE_DOS_SIGNATURE)
    goto fail_format;

  /* Determine the size of the stub  */
  num_pages = H_GET_16 (abfd, filehdr_dos.e_cp);
  last_page_size = H_GET_16 (abfd, filehdr_dos.e_cblp);
  stubsize = num_pages * 512;
  if (last_page_size != 0)
    stubsize += last_page_size - 512;

  ufile_ptr filesize = bfd_get_file_size (abfd);
  if (filesize != 0 && stubsize > filesize)
    goto fail_format;

  /* Save now the stub to be used later.  Put the stub data to a temporary
     location first as tdata still does not exist.  It may not even
     be ever created if we are just checking the file format of ABFD.  */
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    goto fail;
  go32exe_temp_stub = bfd_malloc (stubsize);
  if (go32exe_temp_stub == NULL)
    goto fail;
  if (bfd_read (go32exe_temp_stub, stubsize, abfd) != stubsize)
    goto fail;
  go32exe_temp_stub_size = stubsize;

  /* Confirm that this is a go32stub.  */
  header_end = H_GET_16 (abfd, filehdr_dos.e_cparhdr) * 16UL;
  if (go32exe_temp_stub_size < header_end
      || go32exe_temp_stub_size - header_end < sizeof "go32stub" - 1
      || !startswith (go32exe_temp_stub + header_end, "go32stub"))
    goto fail_format;

  /* Set origin to where the COFF header starts and seek there.  */
  abfd->origin = stubsize;
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    goto fail;

  /* Call coff_object_p to read the COFF image.  If this fails then the file
     must be just a stub with no COFF data attached.  */
  bfd_cleanup cleanup = coff_object_p (abfd);
  if (cleanup == NULL)
    goto fail;
  BFD_ASSERT (cleanup == coff_object_cleanup);

  return go32exe_cleanup;

 fail_format:
  bfd_set_error (bfd_error_wrong_format);
 fail:
  go32exe_cleanup (abfd);
  return NULL;
}

/* Write the stub to the output file, then call coff_write_object_contents.  */

static bool
go32exe_write_object_contents (bfd *abfd)
{
  const bfd_size_type pos = bfd_tell (abfd);
  const bfd_size_type stubsize = coff_data (abfd)->stub_size;

  BFD_ASSERT (stubsize != 0);

  bfd_set_error (bfd_error_system_call);

  /* Write the stub.  */
  abfd->origin = 0;
  if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    return false;
  if (bfd_write (coff_data (abfd)->stub, stubsize, abfd) != stubsize)
    return false;

  /* Seek back to where we were.  */
  abfd->origin = stubsize;
  if (bfd_seek (abfd, pos, SEEK_SET) != 0)
    return false;

  return coff_write_object_contents (abfd);
}

/* mkobject hook.  Called directly through bfd_set_format or via
   coff_mkobject_hook etc from bfd_check_format.  */

static bool
go32exe_mkobject (bfd *abfd)
{
  /* Don't output to an archive.  */
  if (abfd->my_archive != NULL)
    return false;

  if (!_bfd_go32_mkobject (abfd))
    return false;

  go32exe_create_stub (abfd);
  if (coff_data (abfd)->stub == NULL)
    {
      bfd_release (abfd, coff_data (abfd));
      return false;
    }
  abfd->origin = coff_data (abfd)->stub_size;

  return true;
}
