# This shell script emits a C file. -*- C -*-
#   Copyright (C) 2001-2021 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 elf.em and mmo.em, used to define
# MMIX-specific things common to ELF and MMO.

fragment <<EOF
#include "elf/mmix.h"

static void gld${EMULATION_NAME}_before_parse (void);

static void
mmix_before_parse (void)
{
  link_info.check_relocs_after_open_input = true;
  gld${EMULATION_NAME}_before_parse ();
}

/* Set up handling of linker-allocated global registers.  */

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

  /* There's a needrelax.em which uses this ..._before_allocation-hook and
     just has the statement below as payload.  It's more of a hassle to
     use that than to just include these two lines and take the
     maintenance burden to keep them in sync.  (Of course we lose the
     maintenance burden of checking that it still does what we need.)  */

  /* Force -relax on (regardless of whether we're doing a relocatable
     link).  */
  ENABLE_RELAXATION;

  if (!_bfd_mmix_before_linker_allocation (link_info.output_bfd, &link_info))
    einfo (_("%X%P: internal problems setting up section %s"),
	   MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
}

/* We need to set the VMA of the .MMIX.reg_contents section when it has
   been allocated, and produce the final settings for the linker-generated
   GREGs.  */

static void
mmix_after_allocation (void)
{
  asection *sec;
  bfd_signed_vma regvma;

  gld${EMULATION_NAME}_after_allocation ();

  /* If there's no register section, we don't need to do anything.  On the
     other hand, if there's a non-standard linker-script without a mapping
     from MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME when that section is
     present (as in the ld test "NOCROSSREFS 2"), that section (1) will be
     orphaned; not inserted in MMIX_REG_CONTENTS_SECTION_NAME and (2) we
     will not do the necessary preparations for those relocations that
     caused it to be created.  We'll SEGV from the latter error.  The
     former error in separation will result in a non-working binary, but
     that's expected when you play tricks with linker scripts.  The
     "NOCROSSREFS 2" test does not run the output so it does not matter
     there.  */
  sec = bfd_get_section_by_name (link_info.output_bfd,
				 MMIX_REG_CONTENTS_SECTION_NAME);
  if (sec == NULL)
    sec
      = bfd_get_section_by_name (link_info.output_bfd,
				 MMIX_LD_ALLOCATED_REG_CONTENTS_SECTION_NAME);
  if (sec == NULL)
    return;

  regvma = 256 * 8 - sec->size - 8;

  /* If we start on a local register, we have too many global registers.
     We treat this error as nonfatal (meaning processing will continue in
     search for other errors), because it's a link error in the same way
     as an undefined symbol.  */
  if (regvma < 32 * 8)
    {
      einfo (_("%X%P: too many global registers: %u, max 223\n"),
	     (unsigned) sec->size / 8);
      regvma = 32 * 8;
    }

  /* Set vma to correspond to first such register number * 8.  */
  bfd_set_section_vma (sec, (bfd_vma) regvma);

  /* Simplify symbol output for the register section (without contents;
     created for register symbols) by setting the output offset to 0.
     This section is only present when there are register symbols.  */
  sec = bfd_get_section_by_name (link_info.output_bfd, MMIX_REG_SECTION_NAME);
  if (sec != NULL)
    bfd_set_section_vma (sec, 0);

  if (!_bfd_mmix_after_linker_allocation (link_info.output_bfd, &link_info))
    {
      /* This is a fatal error; make einfo call not return.  */
      einfo (_("%F%P: can't finalize linker-allocated global registers\n"));
    }
}
EOF

LDEMUL_BEFORE_PARSE=mmix_before_parse
LDEMUL_AFTER_ALLOCATION=mmix_after_allocation
LDEMUL_BEFORE_ALLOCATION=mmix_before_allocation
