# This shell script emits a C file. -*- C -*-
#   Copyright (C) 2001-2015 Free Software Foundation, Inc.
#
# 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 generic.em.

fragment <<EOF
/* Need to have this macro defined before mmix-elfnmmo, which uses the
   name for the before_allocation function, defined in ldemul.c (for
   the mmo "emulation") or in elf32.em (for the elf64mmix
   "emulation").  */
#define gldmmo_before_allocation before_allocation_default

/* We include this header *not* because we expect to handle ELF here
   but because we re-use the map_segments function in elf-generic.em,
   a file which is rightly somewhat ELF-centric.  But this is only to
   get a weird testcase right; ld-mmix/bpo-22, forcing ELF to be
   output from the mmo emulation: -m mmo --oformat elf64-mmix!  */
#include "elf-bfd.h"

static void gld${EMULATION_NAME}_after_allocation (void);
EOF

source_em ${srcdir}/emultempl/elf-generic.em
source_em ${srcdir}/emultempl/mmix-elfnmmo.em

fragment <<EOF

/* Place an orphan section.  We use this to put random SEC_CODE or
   SEC_READONLY sections right after MMO_TEXT_SECTION_NAME.  Much borrowed
   from elf32.em.  */

static lang_output_section_statement_type *
mmo_place_orphan (asection *s,
		  const char *secname,
		  int constraint ATTRIBUTE_UNUSED)
{
  static struct
  {
    flagword nonzero_flags;
    struct orphan_save orphansave;
  } holds[] =
      {
	{
	  SEC_CODE | SEC_READONLY,
	  {
	    MMO_TEXT_SECTION_NAME,
	    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE,
	    0, 0, 0, 0
	  }
	},
	{
	  SEC_LOAD | SEC_DATA,
	  {
	    MMO_DATA_SECTION_NAME,
	    SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_DATA,
	    0, 0, 0, 0
	  }
	},
	{
	  SEC_ALLOC,
	  {
	    ".bss",
	    SEC_ALLOC,
	    0, 0, 0, 0
	  }
	}
      };

  struct orphan_save *place = NULL;
  lang_output_section_statement_type *after;
  lang_output_section_statement_type *os;
  size_t i;

  /* We have nothing to say for anything other than a final link or
     for sections that are excluded.  */
  if (link_info.type == type_relocatable
      || (s->flags & SEC_EXCLUDE) != 0)
    return NULL;

  os = lang_output_section_find (secname);

  /* We have an output section by this name.  Place the section inside it
     (regardless of whether the linker script lists it as input).  */
  if (os != NULL)
    {
      lang_add_section (&os->children, s, NULL, os);
      return os;
    }

  /* Check for matching section type flags for sections we care about.
     A section without contents can have SEC_LOAD == 0, but we still
     want it attached to a sane section so the symbols appear as
     expected.  */
  if ((s->flags & (SEC_ALLOC | SEC_READONLY)) != SEC_READONLY)
    for (i = 0; i < sizeof (holds) / sizeof (holds[0]); i++)
      if ((s->flags & holds[i].nonzero_flags) != 0)
	{
	  place = &holds[i].orphansave;
	  if (place->os == NULL)
	    place->os = lang_output_section_find (place->name);
	  break;
	}

  if (place == NULL)
    {
      /* For other combinations, we have to give up, except we make
	 sure not to place the orphan section after the
	 linker-generated register section; that'd make it continue
	 the reg section and we never want that to happen for orphan
	 sections.  */
      lang_output_section_statement_type *before;
      lang_output_section_statement_type *lookup;
      static struct orphan_save hold_nonreg =
	{
	  NULL,
	  SEC_READONLY,
	  0, 0, 0, 0
	};

      if (hold_nonreg.os == NULL)
	{
	  before = lang_output_section_find (MMIX_REG_CONTENTS_SECTION_NAME);

	  /* If we have no such section, all fine; we don't care where
	     it's placed.  */
	  if (before == NULL)
	    return NULL;

	  /* We have to find the oss before this one, so we can use that as
	     "after".  */
	  for (lookup = &lang_output_section_statement.head->output_section_statement;
	       lookup != NULL && lookup->next != before;
	       lookup = lookup->next)
	    ;

	  hold_nonreg.os = lookup;
	}

      place = &hold_nonreg;
    }

  after = place->os;
  if (after == NULL)
    return NULL;

  /* If there's an output section by *this* name, we'll use it, regardless
     of actual section flags, in contrast to what's done in elf32.em.  */
  os = lang_insert_orphan (s, secname, 0, after, place, NULL, NULL);

  return os;
}

/* Remove the spurious settings of SEC_RELOC that make it to the output at
   link time.  We are as confused as elflink.h:elf_bfd_final_link, and
   paper over the bug similarly.  */

static void
mmo_wipe_sec_reloc_flag (bfd *abfd, asection *sec, void *ptr ATTRIBUTE_UNUSED)
{
  bfd_set_section_flags (abfd, sec,
			 bfd_get_section_flags (abfd, sec) & ~SEC_RELOC);
}

/* Iterate with bfd_map_over_sections over mmo_wipe_sec_reloc_flag... */

static void
gld${EMULATION_NAME}_after_allocation (void)
{
  bfd_map_over_sections (link_info.output_bfd, mmo_wipe_sec_reloc_flag, NULL);
  gld${EMULATION_NAME}_map_segments (FALSE);
}

/* To get on-demand global register allocation right, we need to parse the
   relocs, like what happens when linking to ELF.  It needs to be done
   before all input sections are supposed to be present.  When linking to
   ELF, it's done when reading symbols.  When linking to mmo, we do it
   when all input files are seen, which is equivalent.  */

static void
mmo_after_open (void)
{
  /* When there's a mismatch between the output format and the emulation
     (using weird combinations like "-m mmo --oformat elf64-mmix" for
     example), we'd count relocs twice because they'd also be counted
     along the usual route for ELF-only linking, which would lead to an
     internal accounting error.  */
  if (bfd_get_flavour (link_info.output_bfd) != bfd_target_elf_flavour)
    {
      LANG_FOR_EACH_INPUT_STATEMENT (is)
	{
	  if (bfd_get_flavour (is->the_bfd) == bfd_target_elf_flavour
	      && !_bfd_mmix_check_all_relocs (is->the_bfd, &link_info))
	    einfo ("%X%P: Internal problems scanning %B after opening it",
		   is->the_bfd);
	}
    }
  after_open_default ();
}
EOF

LDEMUL_PLACE_ORPHAN=mmo_place_orphan
LDEMUL_AFTER_OPEN=mmo_after_open
