# This shell script emits a C file. -*- C -*-
#   Copyright (C) 2000-2015 Free Software Foundation, Inc.
#   Written by Michael Sokolov <msokolov@ivan.Harhan.ORG>, based on armelf.em
#
# This file is part of the GNU Binutils.
#
# 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 is sourced from elf32.em, and defines some extra routines for m68k
# embedded systems using ELF and for some other systems using m68k ELF.  While
# it is sourced from elf32.em for all m68k ELF configurations, here we include
# only the features we want depending on the configuration.

case ${target} in
  m68*-*-elf)
    echo "#define SUPPORT_EMBEDDED_RELOCS" >>e${EMULATION_NAME}.c
    ;;
esac

case ${target} in
  *-linux*)
# Don't use multi-GOT by default due to glibc linker's assumption
# that GOT pointer points to GOT[0].
#   got_handling_target_default=GOT_HANDLING_MULTIGOT
    got_handling_target_default=GOT_HANDLING_SINGLE
    ;;
  *)
    got_handling_target_default=GOT_HANDLING_SINGLE
    ;;
esac

fragment <<EOF

#define GOT_HANDLING_SINGLE   (0)
#define GOT_HANDLING_NEGATIVE (1)
#define GOT_HANDLING_MULTIGOT (2)
#define GOT_HANDLING_TARGET_DEFAULT ${got_handling_target_default}

/* How to generate GOT.  */
static int got_handling = GOT_HANDLING_DEFAULT;

#ifdef SUPPORT_EMBEDDED_RELOCS
static void check_sections (bfd *, asection *, void *);
#endif

/* This function is run after all the input files have been opened.  */

static void
m68k_elf_after_open (void)
{
  /* Call the standard elf routine.  */
  gld${EMULATION_NAME}_after_open ();

#ifdef SUPPORT_EMBEDDED_RELOCS
  if (command_line.embedded_relocs
      && (link_info.type != type_relocatable))
    {
      bfd *abfd;

      /* In the embedded relocs mode we create a .emreloc section for each
	 input file with a nonzero .data section.  The BFD backend will fill in
	 these sections with magic numbers which can be used to relocate the
	 data section at run time.  */
      for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
	{
	  asection *datasec;

	  /* As first-order business, make sure that each input BFD is either
	     COFF or ELF.  We need to call a special BFD backend function to
	     generate the embedded relocs, and we have such functions only for
	     COFF and ELF.  */
	  if (bfd_get_flavour (abfd) != bfd_target_coff_flavour
	      && bfd_get_flavour (abfd) != bfd_target_elf_flavour)
	    einfo ("%F%B: all input objects must be COFF or ELF for --embedded-relocs\n");

	  datasec = bfd_get_section_by_name (abfd, ".data");

	  /* Note that we assume that the reloc_count field has already
	     been set up.  We could call bfd_get_reloc_upper_bound, but
	     that returns the size of a memory buffer rather than a reloc
	     count.  We do not want to call bfd_canonicalize_reloc,
	     because although it would always work it would force us to
	     read in the relocs into BFD canonical form, which would waste
	     a significant amount of time and memory.  */
	  if (datasec != NULL && datasec->reloc_count > 0)
	    {
	      asection *relsec;

	      relsec = bfd_make_section_with_flags (abfd, ".emreloc",
						    (SEC_ALLOC
						    | SEC_LOAD
						    | SEC_HAS_CONTENTS
						    | SEC_IN_MEMORY));
	      if (relsec == NULL
		  || ! bfd_set_section_alignment (abfd, relsec, 2)
		  || ! bfd_set_section_size (abfd, relsec,
					     datasec->reloc_count * 12))
		einfo ("%F%B: can not create .emreloc section: %E\n");
	    }

	  /* Double check that all other data sections are empty, as is
	     required for embedded PIC code.  */
	  bfd_map_over_sections (abfd, check_sections, datasec);
	}
    }
#endif /* SUPPORT_EMBEDDED_RELOCS */
}

#ifdef SUPPORT_EMBEDDED_RELOCS
/* Check that of the data sections, only the .data section has
   relocs.  This is called via bfd_map_over_sections.  */

static void
check_sections (bfd *abfd, asection *sec, void *datasec)
{
  if ((bfd_get_section_flags (abfd, sec) & SEC_DATA)
      && sec != datasec
      && sec->reloc_count != 0)
    einfo ("%B%X: section %s has relocs; can not use --embedded-relocs\n",
	   abfd, bfd_get_section_name (abfd, sec));
}

#endif /* SUPPORT_EMBEDDED_RELOCS */

/* This function is called after the section sizes and offsets have
   been set.  */

static void
m68k_elf_after_allocation (void)
{
  /* Call the standard elf routine.  */
  gld${EMULATION_NAME}_after_allocation ();

#ifdef SUPPORT_EMBEDDED_RELOCS
  if (command_line.embedded_relocs
      && (link_info.type != type_relocatable))
    {
      bfd *abfd;

      /* If we are generating embedded relocs, call a special BFD backend
	 routine to do the work.  */
      for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
	{
	  asection *datasec, *relsec;
	  char *errmsg;

	  datasec = bfd_get_section_by_name (abfd, ".data");

	  if (datasec == NULL || datasec->reloc_count == 0)
	    continue;

	  relsec = bfd_get_section_by_name (abfd, ".emreloc");
	  ASSERT (relsec != NULL);

	  if (bfd_get_flavour (abfd) == bfd_target_coff_flavour)
	    {
	      if (! bfd_m68k_coff_create_embedded_relocs (abfd, &link_info,
							  datasec, relsec,
							  &errmsg))
		{
		  if (errmsg == NULL)
		    einfo ("%B%X: can not create runtime reloc information: %E\n",
			   abfd);
		  else
		    einfo ("%X%B: can not create runtime reloc information: %s\n",
			   abfd, errmsg);
		}
	    }
	  else if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
	    {
	      if (! bfd_m68k_elf32_create_embedded_relocs (abfd, &link_info,
							   datasec, relsec,
							   &errmsg))
		{
		  if (errmsg == NULL)
		    einfo ("%B%X: can not create runtime reloc information: %E\n",
			   abfd);
		  else
		    einfo ("%X%B: can not create runtime reloc information: %s\n",
			   abfd, errmsg);
		}
	    }
	  else
	    abort ();
	}
    }
#endif /* SUPPORT_EMBEDDED_RELOCS */
}

/* This is a convenient point to tell BFD about target specific flags.
   After the output has been created, but before inputs are read.  */

static void
elf_m68k_create_output_section_statements (void)
{
  bfd_elf_m68k_set_target_options (&link_info, got_handling);
}

EOF

# Define some shell vars to insert bits of code into the standard elf
# parse_args and list_options functions.
#
PARSE_AND_LIST_PROLOGUE='
#define OPTION_GOT	301
'

PARSE_AND_LIST_LONGOPTS='
  { "got", required_argument, NULL, OPTION_GOT},
'

PARSE_AND_LIST_OPTIONS='
  fprintf (file, _("  --got=<type>                Specify GOT handling scheme\n"));
'

PARSE_AND_LIST_ARGS_CASES='
    case OPTION_GOT:
      if (strcmp (optarg, "target") == 0)
        got_handling = GOT_HANDLING_TARGET_DEFAULT;
      else if (strcmp (optarg, "single") == 0)
        got_handling = 0;
      else if (strcmp (optarg, "negative") == 0)
        got_handling = 1;
      else if (strcmp (optarg, "multigot") == 0)
        got_handling = 2;
      else
        einfo (_("Unrecognized --got argument '\''%s'\''.\n"), optarg);
      break;
'

# We have our own after_open and after_allocation functions, but they call
# the standard routines, so give them a different name.
LDEMUL_AFTER_OPEN=m68k_elf_after_open
LDEMUL_AFTER_ALLOCATION=m68k_elf_after_allocation
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=elf_m68k_create_output_section_statements
