# This shell script emits a C file. -*- C -*-
# Copyright (C) 2007-2016 Free Software Foundation, Inc.
# Contributed by M R Swami Reddy <MR.Swami.Reddy@nsc.com>
#
# 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 extra cr16-elf
# specific routines.
#
fragment <<EOF

#include "ldctor.h"

static void check_sections (bfd *, asection *, void *);


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

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

   if (command_line.embedded_relocs
       && !bfd_link_relocatable (&link_info))
     {
       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.rel");

	  /* 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 (abfd, ".emreloc");
	      if (relsec == NULL
		  || ! bfd_set_section_flags (abfd, relsec,
					      (SEC_ALLOC
					       | SEC_LOAD
					       | SEC_HAS_CONTENTS
					       | SEC_IN_MEMORY))
		  || ! bfd_set_section_alignment (abfd, relsec, 2)
		  || ! bfd_set_section_size (abfd, relsec,
					     datasec->reloc_count * 8))
		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);
	}
    }
}

/* 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 ((strncmp (bfd_get_section_name (abfd, sec), ".data.rel", 9) == 0)
     && 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));
}

static void
cr16elf_after_parse (void)
{
  /* Always behave as if called with --sort-common command line
     option.
     This is to emulate the CRTools' method of keeping variables
     of different alignment in separate sections.  */
  config.sort_common = TRUE;

  /* Don't create a demand-paged executable, since this feature isn't
     meaninful in CR16 embedded systems. Moreover, when magic_demand_paged
     is true the link sometimes fails.  */
  config.magic_demand_paged = FALSE;

  gld${EMULATION_NAME}_after_parse ();
}

/* This is called after the sections have been attached to output
   sections, but before any sizes or addresses have been set.  */

static void
cr16elf_before_allocation (void)
{
  /* Call the default first.  */
  gld${EMULATION_NAME}_before_allocation ();

   if (command_line.embedded_relocs
       && (!bfd_link_relocatable (&link_info)))
     {

   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.rel");

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

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

	  if (! bfd_cr16_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);
		}
       }
     }

  /* Enable relaxation by default if the "--no-relax" option was not
     specified.  This is done here instead of in the before_parse hook
     because there is a check in main() to prohibit use of --relax and
     -r together.  */
  if (RELAXATION_DISABLED_BY_DEFAULT)
    ENABLE_RELAXATION;
}

EOF

# Put these extra cr16-elf routines in ld_${EMULATION_NAME}_emulation
#
LDEMUL_AFTER_OPEN=cr16_elf_after_open
LDEMUL_AFTER_PARSE=cr16elf_after_parse
LDEMUL_BEFORE_ALLOCATION=cr16elf_before_allocation
