# This shell script emits a C file. -*- C -*-
#   Copyright (C) 2003-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 defines extra xtensa-elf
# specific routines.
#
fragment <<EOF

#include <xtensa-config.h>
#include "../bfd/elf-bfd.h"
#include "elf/xtensa.h"
#include "bfd.h"

/* Provide default values for new configuration settings.  */
#ifndef XTHAL_ABI_UNDEFINED
#define XTHAL_ABI_UNDEFINED -1
#endif

#ifndef XTHAL_ABI_WINDOWED
#define XTHAL_ABI_WINDOWED 0
#endif

#ifndef XTHAL_ABI_CALL0
#define XTHAL_ABI_CALL0 1
#endif

static void xtensa_wild_group_interleave (lang_statement_union_type *);
static void xtensa_colocate_output_literals (lang_statement_union_type *);
static void xtensa_strip_inconsistent_linkonce_sections
  (lang_statement_list_type *);


/* This number is irrelevant until we turn on use_literal_pages */
static bfd_vma xtensa_page_power = 12; /* 4K pages.  */

/* To force a page break between literals and text, change
   xtensa_use_literal_pages to "true".  */
static bool xtensa_use_literal_pages = false;

#define EXTRA_VALIDATION 0

/* Xtensa ABI.
   This option is defined in BDF library.  */
extern int elf32xtensa_abi;


static char *
elf_xtensa_choose_target (int argc ATTRIBUTE_UNUSED,
			  char **argv ATTRIBUTE_UNUSED)
{
  if (XCHAL_HAVE_BE)
    return "${BIG_OUTPUT_FORMAT}";
  else
    return "${LITTLE_OUTPUT_FORMAT}";
}


static void
elf_xtensa_before_parse (void)
{
  /* Just call the default hook.... Tensilica's version of this function
     does some other work that isn't relevant here.  */
  gld${EMULATION_NAME}_before_parse ();
}


static void
remove_section (bfd *abfd, asection *os)
{
  asection **spp;
  for (spp = &abfd->sections; *spp; spp = &(*spp)->next)
    if (*spp == os)
      {
	*spp = os->next;
	os->owner->section_count--;
	break;
      }
}


static bool
replace_insn_sec_with_prop_sec (bfd *abfd,
				const char *insn_sec_name,
				const char *prop_sec_name,
				char **error_message)
{
  asection *insn_sec;
  asection *prop_sec;
  bfd_byte *prop_contents = NULL;
  bfd_byte *insn_contents = NULL;
  unsigned entry_count;
  unsigned entry;
  Elf_Internal_Shdr *rel_hdr;
  Elf_Internal_Rela *internal_relocs = NULL;
  unsigned reloc_count;

  *error_message = "";
  insn_sec = bfd_get_section_by_name (abfd, insn_sec_name);
  if (insn_sec == NULL)
    return true;
  entry_count = insn_sec->size / 8;

  prop_sec = bfd_get_section_by_name (abfd, prop_sec_name);
  if (prop_sec != NULL && insn_sec != NULL)
    {
      *error_message = _("file already has property tables");
      return false;
    }

  if (insn_sec->size != 0)
    {
      insn_contents = (bfd_byte *) xmalloc (insn_sec->size);
      if (! bfd_get_section_contents (abfd, insn_sec, insn_contents,
				      (file_ptr) 0, insn_sec->size))
	{
	  *error_message = _("failed to read section contents");
	  goto cleanup;
	}
    }

  /* Create a property table section for it.  */
  prop_sec_name = strdup (prop_sec_name);
  prop_sec = bfd_make_section_with_flags
    (abfd, prop_sec_name, bfd_section_flags (insn_sec));
  if (prop_sec == NULL
      || !bfd_set_section_alignment (prop_sec, 2))
    {
      *error_message = _("could not create new section");
      goto cleanup;
    }

  prop_sec->size = entry_count * 12;
  prop_contents = (bfd_byte *) bfd_zalloc (abfd, prop_sec->size);
  elf_section_data (prop_sec)->this_hdr.contents = prop_contents;

  /* The entry size and size must be set to allow the linker to compute
     the number of relocations since it does not use reloc_count.  */
  rel_hdr = _bfd_elf_single_rel_hdr (prop_sec);
  rel_hdr->sh_entsize = sizeof (Elf32_External_Rela);
  rel_hdr->sh_size = _bfd_elf_single_rel_hdr (insn_sec)->sh_size;

  if (prop_contents == NULL && prop_sec->size != 0)
    {
      *error_message = _("could not allocate section contents");
      goto cleanup;
    }

  /* Read the relocations.  */
  reloc_count = insn_sec->reloc_count;
  if (reloc_count != 0)
    {
      /* If there is already an internal_reloc, then save it so that the
	 read_relocs function freshly allocates a copy.  */
      Elf_Internal_Rela *saved_relocs = elf_section_data (insn_sec)->relocs;

      elf_section_data (insn_sec)->relocs = NULL;
      internal_relocs =
	_bfd_elf_link_read_relocs (abfd, insn_sec, NULL, NULL, false);
      elf_section_data (insn_sec)->relocs = saved_relocs;

      if (internal_relocs == NULL)
	{
	  *error_message = _("out of memory");
	  goto cleanup;
	}
    }

  /* Create a relocation section for the property section.  */
  if (internal_relocs != NULL)
    {
      elf_section_data (prop_sec)->relocs = internal_relocs;
      prop_sec->reloc_count = reloc_count;
    }

  /* Now copy each insn table entry to the prop table entry with
     appropriate flags.  */
  for (entry = 0; entry < entry_count; ++entry)
    {
      unsigned value;
      unsigned flags = (XTENSA_PROP_INSN | XTENSA_PROP_NO_TRANSFORM
			| XTENSA_PROP_INSN_NO_REORDER);
      value = bfd_get_32 (abfd, insn_contents + entry * 8 + 0);
      bfd_put_32 (abfd, value, prop_contents + entry * 12 + 0);
      value = bfd_get_32 (abfd, insn_contents + entry * 8 + 4);
      bfd_put_32 (abfd, value, prop_contents + entry * 12 + 4);
      bfd_put_32 (abfd, flags, prop_contents + entry * 12 + 8);
    }

  /* Now copy all of the relocations.  Change offsets for the
     instruction table section to offsets in the property table
     section.  */
  if (internal_relocs)
    {
      unsigned i;

      for (i = 0; i < reloc_count; i++)
	{
	  Elf_Internal_Rela *rela;
	  unsigned r_offset;

	  rela = &internal_relocs[i];

	  /* If this relocation is to the .xt.insn section,
	     change the section number and the offset.  */
	  r_offset = rela->r_offset;
	  r_offset += 4 * (r_offset / 8);
	  rela->r_offset = r_offset;
	}
    }

  remove_section (abfd, insn_sec);

  free (insn_contents);

  return true;

 cleanup:
  if (prop_sec && prop_sec->owner)
    remove_section (abfd, prop_sec);
  free (insn_contents);
  free (internal_relocs);

  return false;
}


#define PROP_SEC_BASE_NAME ".xt.prop"
#define INSN_SEC_BASE_NAME ".xt.insn"
#define LINKONCE_SEC_OLD_TEXT_BASE_NAME ".gnu.linkonce.x."


static void
replace_instruction_table_sections (bfd *abfd, asection *sec)
{
  char *message = "";
  const char *insn_sec_name = NULL;
  char *prop_sec_name = NULL;
  char *owned_prop_sec_name = NULL;
  const char *sec_name;

  sec_name = bfd_section_name (sec);
  if (strcmp (sec_name, INSN_SEC_BASE_NAME) == 0)
    {
      insn_sec_name = INSN_SEC_BASE_NAME;
      prop_sec_name = PROP_SEC_BASE_NAME;
    }
  else if (startswith (sec_name, LINKONCE_SEC_OLD_TEXT_BASE_NAME))
    {
      insn_sec_name = sec_name;
      owned_prop_sec_name = (char *) xmalloc (strlen (sec_name) + 20);
      prop_sec_name = owned_prop_sec_name;
      strcpy (prop_sec_name, ".gnu.linkonce.prop.t.");
      strcat (prop_sec_name,
	      sec_name + strlen (LINKONCE_SEC_OLD_TEXT_BASE_NAME));
    }
  if (insn_sec_name != NULL)
    {
      if (! replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name,
					    &message))
	{
	  einfo (_("%P: warning: failed to convert %s table in %pB (%s); subsequent disassembly may be incomplete\n"),
		 insn_sec_name, abfd, message);
	}
    }
  free (owned_prop_sec_name);
}


/* This is called after all input sections have been opened to convert
   instruction tables (.xt.insn, gnu.linkonce.x.*) tables into property
   tables (.xt.prop) before any section placement.  */

static void
elf_xtensa_after_open (void)
{
  /* First call the ELF version.  */
  gld${EMULATION_NAME}_after_open ();

  /* Now search the input files looking for instruction table sections.  */
  LANG_FOR_EACH_INPUT_STATEMENT (f)
    {
      asection *sec = f->the_bfd->sections;
      asection *next_sec;

      /* Do not use bfd_map_over_sections here since we are removing
	 sections as we iterate.  */
      while (sec != NULL)
	{
	  next_sec = sec->next;
	  replace_instruction_table_sections (f->the_bfd, sec);
	  sec = next_sec;
	}
    }
}


static bool
xt_config_info_unpack_and_check (char *data,
				 bool *pmismatch,
				 char **pmsg)
{
  char *d, *key;
  int num;

  *pmismatch = false;

  d = data;
  while (*d)
    {
      key = d;
      d = strchr (d, '=');
      if (! d)
	goto error;

      /* Overwrite the equal sign.  */
      *d++ = 0;

      /* Check if this is a quoted string or a number.  */
      if (*d == '"')
	{
	  /* No string values are currently checked by LD;
	     just skip over the quotes.  */
	  d++;
	  d = strchr (d, '"');
	  if (! d)
	    goto error;
	  /* Overwrite the trailing quote.  */
	  *d++ = 0;
	}
      else
	{
	  if (*d == 0)
	    goto error;
	  num = strtoul (d, &d, 0);

	  if (! strcmp (key, "ABI"))
	    {
	      if (elf32xtensa_abi == XTHAL_ABI_UNDEFINED)
		{
		  elf32xtensa_abi = num;
		}
	      else if (num != elf32xtensa_abi)
		{
		  *pmismatch = true;
		  *pmsg = "ABI does not match";
		}
	    }
	  else if (! strcmp (key, "USE_ABSOLUTE_LITERALS"))
	    {
	      if (num != XSHAL_USE_ABSOLUTE_LITERALS)
		{
		  *pmismatch = true;
		  *pmsg = "incompatible use of the Extended L32R option";
		}
	    }
	}

      if (*d++ != '\n')
	goto error;
    }

  return true;

 error:
  return false;
}


#define XTINFO_NAME "Xtensa_Info"
#define XTINFO_NAMESZ 12
#define XTINFO_TYPE 1

static void
check_xtensa_info (bfd *abfd, asection *info_sec)
{
  char *data, *errmsg = "";
  bool mismatch;

  data = xmalloc (info_sec->size);
  if (! bfd_get_section_contents (abfd, info_sec, data, 0, info_sec->size))
    einfo (_("%F%P: %pB: cannot read contents of section %pA\n"), abfd, info_sec);

  if (info_sec->size > 24
      && info_sec->size >= 24 + bfd_get_32 (abfd, data + 4)
      && bfd_get_32 (abfd, data + 0) == XTINFO_NAMESZ
      && bfd_get_32 (abfd, data + 8) == XTINFO_TYPE
      && strcmp (data + 12, XTINFO_NAME) == 0
      && xt_config_info_unpack_and_check (data + 12 + XTINFO_NAMESZ,
					  &mismatch, &errmsg))
    {
      if (mismatch)
	einfo (_("%P: %pB: warning: incompatible Xtensa configuration (%s)\n"),
	       abfd, errmsg);
    }
  else
    einfo (_("%P: %pB: warning: cannot parse .xtensa.info section\n"), abfd);

  free (data);
}


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

static void
elf_xtensa_before_allocation (void)
{
  asection *info_sec, *first_info_sec;
  bfd *first_bfd;
  bool is_big_endian = XCHAL_HAVE_BE;

  /* Check that the output endianness matches the Xtensa
     configuration.  The BFD library always includes both big and
     little endian target vectors for Xtensa, but it only supports the
     detailed instruction encode/decode operations (such as are
     required to process relocations) for the selected Xtensa
     configuration.  */

  if (is_big_endian
      && link_info.output_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
    {
      einfo (_("%F%P: little endian output does not match "
	       "Xtensa configuration\n"));
    }
  if (!is_big_endian
      && link_info.output_bfd->xvec->byteorder == BFD_ENDIAN_BIG)
    {
      einfo (_("%F%P: big endian output does not match "
	       "Xtensa configuration\n"));
    }

  /* Keep track of the first input .xtensa.info section, and as a fallback,
     the first input bfd where a .xtensa.info section could be created.
     After the input .xtensa.info has been checked, the contents of the
     first one will be replaced with the output .xtensa.info table.  */
  first_info_sec = 0;
  first_bfd = 0;

  LANG_FOR_EACH_INPUT_STATEMENT (f)
    {
      /* Check that the endianness for each input file matches the output.
	 The merge_private_bfd_data hook has already reported any mismatches
	 as errors, but those errors are not fatal.  At this point, we
	 cannot go any further if there are any mismatches.  */
      if ((is_big_endian && f->the_bfd->xvec->byteorder == BFD_ENDIAN_LITTLE)
	  || (!is_big_endian && f->the_bfd->xvec->byteorder == BFD_ENDIAN_BIG))
	einfo (_("%F%P: cross-endian linking for %pB not supported\n"),
	       f->the_bfd);

      if (! first_bfd)
	first_bfd = f->the_bfd;

      info_sec = bfd_get_section_by_name (f->the_bfd, ".xtensa.info");
      if (! info_sec)
	continue;

      if (! first_info_sec)
	first_info_sec = info_sec;

      /* Unpack the .xtensa.info section and check it against the current
	 Xtensa configuration.  */
      check_xtensa_info (f->the_bfd, info_sec);

      /* Do not include this copy of .xtensa.info in the output.  */
      info_sec->size = 0;
      info_sec->flags |= SEC_EXCLUDE;
    }

  /* Reuse the first .xtensa.info input section to hold the output
     .xtensa.info; or, if none were found, create a new section in the
     first input bfd (assuming there is one).  */
  info_sec = first_info_sec;
  if (! info_sec && first_bfd)
    {
      info_sec = bfd_make_section_with_flags (first_bfd, ".xtensa.info",
					      SEC_HAS_CONTENTS | SEC_READONLY);
      if (! info_sec)
	einfo (_("%F%P: failed to create .xtensa.info section\n"));
    }
  if (info_sec)
    {
      int xtensa_info_size;
      char *data;

      info_sec->flags &= ~SEC_EXCLUDE;
      info_sec->flags |= SEC_IN_MEMORY;

      data = xmalloc (100);
      sprintf (data, "USE_ABSOLUTE_LITERALS=%d\nABI=%d\n",
	       XSHAL_USE_ABSOLUTE_LITERALS, xtensa_abi_choice ());
      xtensa_info_size = strlen (data) + 1;

      /* Add enough null terminators to pad to a word boundary.  */
      do
	data[xtensa_info_size++] = 0;
      while ((xtensa_info_size & 3) != 0);

      info_sec->size = 12 + XTINFO_NAMESZ + xtensa_info_size;
      info_sec->contents = xmalloc (info_sec->size);
      bfd_put_32 (info_sec->owner, XTINFO_NAMESZ, info_sec->contents + 0);
      bfd_put_32 (info_sec->owner, xtensa_info_size, info_sec->contents + 4);
      bfd_put_32 (info_sec->owner, XTINFO_TYPE, info_sec->contents + 8);
      memcpy (info_sec->contents + 12, XTINFO_NAME, XTINFO_NAMESZ);
      memcpy (info_sec->contents + 12 + XTINFO_NAMESZ, data, xtensa_info_size);
      free (data);
    }

  /* 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 and that combination should be allowed for Xtensa.  */
  if (RELAXATION_DISABLED_BY_DEFAULT)
    ENABLE_RELAXATION;

  xtensa_strip_inconsistent_linkonce_sections (stat_ptr);

  gld${EMULATION_NAME}_before_allocation ();

  xtensa_wild_group_interleave (stat_ptr->head);

  if (RELAXATION_ENABLED)
    xtensa_colocate_output_literals (stat_ptr->head);

  /* TBD: We need to force the page alignments to here and only do
     them as needed for the entire output section.  Finally, if this
     is a relocatable link then we need to add alignment notes so
     that the literals can be separated later.  */
}


typedef struct wildcard_list section_name_list;

typedef struct reloc_deps_e_t reloc_deps_e;
typedef struct reloc_deps_section_t reloc_deps_section;
typedef struct reloc_deps_graph_t reloc_deps_graph;


struct reloc_deps_e_t
{
  asection *src; /* Contains l32rs.  */
  asection *tgt; /* Contains literals.  */
  reloc_deps_e *next;
};

/* Place these in the userdata field.  */
struct reloc_deps_section_t
{
  reloc_deps_e *preds;
  reloc_deps_e *succs;
  bool is_only_literal;
};


struct reloc_deps_graph_t
{
  size_t count;
  size_t size;
  asection **sections;
};

static void xtensa_layout_wild
  (const reloc_deps_graph *, lang_wild_statement_type *);

typedef void (*deps_callback_t) (asection *, /* src_sec */
				 bfd_vma,    /* src_offset */
				 asection *, /* target_sec */
				 bfd_vma,    /* target_offset */
				 void *);    /* closure */

extern bool xtensa_callback_required_dependence
  (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *);
static void xtensa_ldlang_clear_addresses (lang_statement_union_type *);
static bool ld_local_file_relocations_fit
  (lang_statement_union_type *, const reloc_deps_graph *);
static bfd_vma ld_assign_relative_paged_dot
  (bfd_vma, lang_statement_union_type *, const reloc_deps_graph *,
   bool);
static bfd_vma ld_xtensa_insert_page_offsets
  (bfd_vma, lang_statement_union_type *, reloc_deps_graph *, bool);
#if EXTRA_VALIDATION
static size_t ld_count_children (lang_statement_union_type *);
#endif

extern lang_statement_list_type constructor_list;

static reloc_deps_section *
xtensa_get_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
			 asection *sec)
{
  /* We have a separate function for this so that
     we could in the future keep a completely independent
     structure that maps a section to its dependence edges.
     For now, we place these in the sec->userdata field.
     This doesn't clash with ldlang.c use of userdata for output
     sections, and during map output for input sections, since the
     xtensa use is only for input sections and only extant in
     before_allocation.  */
  reloc_deps_section *sec_deps = bfd_section_userdata (sec);
  return sec_deps;
}

static void
xtensa_set_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
			 asection *sec,
			 reloc_deps_section *deps_section)
{
  bfd_set_section_userdata (sec, deps_section);
}


/* This is used to keep a list of all of the sections participating in
   the graph so we can clean them up quickly.  */

static void
xtensa_append_section_deps (reloc_deps_graph *deps, asection *sec)
{
  if (deps->size <= deps->count)
    {
      asection **new_sections;
      size_t i;
      size_t new_size;

      new_size = deps->size * 2;
      if (new_size == 0)
	new_size = 20;

      new_sections = xmalloc (sizeof (asection *) * new_size);
      memset (new_sections, 0, sizeof (asection *) * new_size);
      for (i = 0; i < deps->count; i++)
	{
	  new_sections[i] = deps->sections[i];
	}
      free (deps->sections);
      deps->sections = new_sections;
      deps->size = new_size;
    }
  deps->sections[deps->count] = sec;
  deps->count++;
}


static void
free_reloc_deps_graph (reloc_deps_graph *deps)
{
  size_t i;
  for (i = 0; i < deps->count; i++)
    {
      asection *sec = deps->sections[i];
      reloc_deps_section *sec_deps;
      sec_deps = xtensa_get_section_deps (deps, sec);
      if (sec_deps)
	{
	  reloc_deps_e *next;
	  while (sec_deps->succs != NULL)
	    {
	      next = sec_deps->succs->next;
	      free (sec_deps->succs);
	      sec_deps->succs = next;
	    }

	  while (sec_deps->preds != NULL)
	    {
	      next = sec_deps->preds->next;
	      free (sec_deps->preds);
	      sec_deps->preds = next;
	    }
	  free (sec_deps);
	}
      xtensa_set_section_deps (deps, sec, NULL);
    }
  free (deps->sections);
  free (deps);
}


static bool
section_is_source (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
		   lang_statement_union_type *s)
{
  asection *sec;
  const reloc_deps_section *sec_deps;

  if (s->header.type != lang_input_section_enum)
    return false;
  sec = s->input_section.section;

  sec_deps = xtensa_get_section_deps (deps, sec);
  return sec_deps && sec_deps->succs != NULL;
}


static bool
section_is_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
		   lang_statement_union_type *s)
{
  asection *sec;
  const reloc_deps_section *sec_deps;

  if (s->header.type != lang_input_section_enum)
    return false;
  sec = s->input_section.section;

  sec_deps = xtensa_get_section_deps (deps, sec);
  return sec_deps && sec_deps->preds != NULL;
}


static bool
section_is_source_or_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
			     lang_statement_union_type *s)
{
  return (section_is_source (deps, s)
	  || section_is_target (deps, s));
}


typedef struct xtensa_ld_iter_stack_t xtensa_ld_iter_stack;
typedef struct xtensa_ld_iter_t xtensa_ld_iter;

struct xtensa_ld_iter_t
{
  lang_statement_union_type *parent;	/* Parent of the list.  */
  lang_statement_list_type *l;		/* List that holds it.  */
  lang_statement_union_type **loc;	/* Place in the list.  */
};

struct xtensa_ld_iter_stack_t
{
  xtensa_ld_iter iterloc;		/* List that hold it.  */

  xtensa_ld_iter_stack *next;		/* Next in the stack.  */
  xtensa_ld_iter_stack *prev;		/* Back pointer for stack.  */
};


static void
ld_xtensa_move_section_after (xtensa_ld_iter *to, xtensa_ld_iter *current)
{
  lang_statement_union_type *to_next;
  lang_statement_union_type *current_next;
  lang_statement_union_type **e;

#if EXTRA_VALIDATION
  size_t old_to_count, new_to_count;
  size_t old_current_count, new_current_count;
#endif

  if (to == current)
    return;

#if EXTRA_VALIDATION
  old_to_count = ld_count_children (to->parent);
  old_current_count = ld_count_children (current->parent);
#endif

  to_next = *(to->loc);
  current_next = (*current->loc)->header.next;

  *(to->loc) = *(current->loc);

  *(current->loc) = current_next;
  (*(to->loc))->header.next = to_next;

  /* reset "to" list tail */
  for (e = &to->l->head; *e != NULL; e = &(*e)->header.next)
    ;
  to->l->tail = e;

  /* reset "current" list tail */
  for (e = &current->l->head; *e != NULL; e = &(*e)->header.next)
    ;
  current->l->tail = e;

#if EXTRA_VALIDATION
  new_to_count = ld_count_children (to->parent);
  new_current_count = ld_count_children (current->parent);

  ASSERT ((old_to_count + old_current_count)
	  == (new_to_count + new_current_count));
#endif
}


/* Can only be called with lang_statements that have lists.  Returns
   FALSE if the list is empty.  */

static bool
iter_stack_empty (xtensa_ld_iter_stack **stack_p)
{
  return *stack_p == NULL;
}


static bool
iter_stack_push (xtensa_ld_iter_stack **stack_p,
		 lang_statement_union_type *parent)
{
  xtensa_ld_iter_stack *stack;
  lang_statement_list_type *l = NULL;

  switch (parent->header.type)
    {
    case lang_output_section_statement_enum:
      l = &parent->output_section_statement.children;
      break;
    case lang_wild_statement_enum:
      l = &parent->wild_statement.children;
      break;
    case lang_group_statement_enum:
      l = &parent->group_statement.children;
      break;
    default:
      ASSERT (0);
      return false;
    }

  /* Empty. do not push.  */
  if (l->tail == &l->head)
    return false;

  stack = xmalloc (sizeof (xtensa_ld_iter_stack));
  memset (stack, 0, sizeof (xtensa_ld_iter_stack));
  stack->iterloc.parent = parent;
  stack->iterloc.l = l;
  stack->iterloc.loc = &l->head;

  stack->next = *stack_p;
  stack->prev = NULL;
  if (*stack_p != NULL)
    (*stack_p)->prev = stack;
  *stack_p = stack;
  return true;
}


static void
iter_stack_pop (xtensa_ld_iter_stack **stack_p)
{
  xtensa_ld_iter_stack *stack;

  stack = *stack_p;

  if (stack == NULL)
    {
      ASSERT (stack != NULL);
      return;
    }

  if (stack->next != NULL)
    stack->next->prev = NULL;

  *stack_p = stack->next;
  free (stack);
}


/* This MUST be called if, during iteration, the user changes the
   underlying structure.  It will check for a NULL current and advance
   accordingly.  */

static void
iter_stack_update (xtensa_ld_iter_stack **stack_p)
{
  if (!iter_stack_empty (stack_p)
      && (*(*stack_p)->iterloc.loc) == NULL)
    {
      iter_stack_pop (stack_p);

      while (!iter_stack_empty (stack_p)
	     && ((*(*stack_p)->iterloc.loc)->header.next == NULL))
	{
	  iter_stack_pop (stack_p);
	}
      if (!iter_stack_empty (stack_p))
	(*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next;
    }
}


static void
iter_stack_next (xtensa_ld_iter_stack **stack_p)
{
  xtensa_ld_iter_stack *stack;
  lang_statement_union_type *current;
  stack = *stack_p;

  current = *stack->iterloc.loc;
  /* If we are on the first element.  */
  if (current != NULL)
    {
      switch (current->header.type)
	{
	case lang_output_section_statement_enum:
	case lang_wild_statement_enum:
	case lang_group_statement_enum:
	  /* If the list if not empty, we are done.  */
	  if (iter_stack_push (stack_p, *stack->iterloc.loc))
	    return;
	  /* Otherwise increment the pointer as normal.  */
	  break;
	default:
	  break;
	}
    }

  while (!iter_stack_empty (stack_p)
	 && ((*(*stack_p)->iterloc.loc)->header.next == NULL))
    {
      iter_stack_pop (stack_p);
    }
  if (!iter_stack_empty (stack_p))
    (*stack_p)->iterloc.loc = &(*(*stack_p)->iterloc.loc)->header.next;
}


static lang_statement_union_type *
iter_stack_current (xtensa_ld_iter_stack **stack_p)
{
  return *((*stack_p)->iterloc.loc);
}


/* The iter stack is a preorder.  */

static void
iter_stack_create (xtensa_ld_iter_stack **stack_p,
		   lang_statement_union_type *parent)
{
  iter_stack_push (stack_p, parent);
}


static void
iter_stack_copy_current (xtensa_ld_iter_stack **stack_p, xtensa_ld_iter *front)
{
  *front = (*stack_p)->iterloc;
}


static void
xtensa_colocate_literals (reloc_deps_graph *deps,
			  lang_statement_union_type *statement)
{
  /* Keep a stack of pointers to control iteration through the contours.  */
  xtensa_ld_iter_stack *stack = NULL;
  xtensa_ld_iter_stack **stack_p = &stack;

  xtensa_ld_iter front;  /* Location where new insertion should occur.  */
  xtensa_ld_iter *front_p = NULL;

  xtensa_ld_iter current; /* Location we are checking.  */
  xtensa_ld_iter *current_p = NULL;
  bool in_literals = false;

  if (deps->count == 0)
    return;

  iter_stack_create (stack_p, statement);

  while (!iter_stack_empty (stack_p))
    {
      bool skip_increment = false;
      lang_statement_union_type *l = iter_stack_current (stack_p);

      switch (l->header.type)
	{
	case lang_assignment_statement_enum:
	  /* Any assignment statement should block reordering across it.  */
	  front_p = NULL;
	  in_literals = false;
	  break;

	case lang_input_section_enum:
	  if (front_p == NULL)
	    {
	      in_literals = (section_is_target (deps, l)
			     && !section_is_source (deps, l));
	      if (in_literals)
		{
		  front_p = &front;
		  iter_stack_copy_current (stack_p, front_p);
		}
	    }
	  else
	    {
	      bool is_target;
	      current_p = &current;
	      iter_stack_copy_current (stack_p, current_p);
	      is_target = (section_is_target (deps, l)
			   && !section_is_source (deps, l));

	      if (in_literals)
		{
		  iter_stack_copy_current (stack_p, front_p);
		  if (!is_target)
		    in_literals = false;
		}
	      else
		{
		  if (is_target)
		    {
		      /* Try to insert in place.  */
		      ld_xtensa_move_section_after (front_p, current_p);
		      ld_assign_relative_paged_dot (0x100000,
						    statement,
						    deps,
						    xtensa_use_literal_pages);

		      /* We use this code because it's already written.  */
		      if (!ld_local_file_relocations_fit (statement, deps))
			{
			  /* Move it back.  */
			  ld_xtensa_move_section_after (current_p, front_p);
			  /* Reset the literal placement.  */
			  iter_stack_copy_current (stack_p, front_p);
			}
		      else
			{
			  /* Move front pointer up by one.  */
			  front_p->loc = &(*front_p->loc)->header.next;

			  /* Do not increment the current pointer.  */
			  skip_increment = true;
			}
		    }
		}
	    }
	  break;
	default:
	  break;
	}

      if (!skip_increment)
	iter_stack_next (stack_p);
      else
	/* Be careful to update the stack_p if it now is a null.  */
	iter_stack_update (stack_p);
    }

  lang_for_each_statement_worker (xtensa_ldlang_clear_addresses, statement);
}


static void
xtensa_move_dependencies_to_front (reloc_deps_graph *deps,
				   lang_wild_statement_type *w)
{
  /* Keep a front pointer and a current pointer.  */
  lang_statement_union_type **front;
  lang_statement_union_type **current;

  /* Walk to the end of the targets.  */
  for (front = &w->children.head;
       (*front != NULL) && section_is_source_or_target (deps, *front);
       front = &(*front)->header.next)
    ;

  if (*front == NULL)
    return;

  current = &(*front)->header.next;
  while (*current != NULL)
    {
      if (section_is_source_or_target (deps, *current))
	{
	  /* Insert in place.  */
	  xtensa_ld_iter front_iter;
	  xtensa_ld_iter current_iter;

	  front_iter.parent = (lang_statement_union_type *) w;
	  front_iter.l = &w->children;
	  front_iter.loc = front;

	  current_iter.parent = (lang_statement_union_type *) w;
	  current_iter.l = &w->children;
	  current_iter.loc = current;

	  ld_xtensa_move_section_after (&front_iter, &current_iter);
	  front = &(*front)->header.next;
	}
      else
	{
	  current = &(*current)->header.next;
	}
    }
}


static bool
deps_has_sec_edge (const reloc_deps_graph *deps, asection *src, asection *tgt)
{
  const reloc_deps_section *sec_deps;
  const reloc_deps_e *sec_deps_e;

  sec_deps = xtensa_get_section_deps (deps, src);
  if (sec_deps == NULL)
    return false;

  for (sec_deps_e = sec_deps->succs;
       sec_deps_e != NULL;
       sec_deps_e = sec_deps_e->next)
    {
      ASSERT (sec_deps_e->src == src);
      if (sec_deps_e->tgt == tgt)
	return true;
    }
  return false;
}


static bool
deps_has_edge (const reloc_deps_graph *deps,
	       lang_statement_union_type *src,
	       lang_statement_union_type *tgt)
{
  if (!section_is_source (deps, src))
    return false;
  if (!section_is_target (deps, tgt))
    return false;

  if (src->header.type != lang_input_section_enum)
    return false;
  if (tgt->header.type != lang_input_section_enum)
    return false;

  return deps_has_sec_edge (deps, src->input_section.section,
			    tgt->input_section.section);
}


static void
add_deps_edge (reloc_deps_graph *deps, asection *src_sec, asection *tgt_sec)
{
  reloc_deps_section *src_sec_deps;
  reloc_deps_section *tgt_sec_deps;

  reloc_deps_e *src_edge;
  reloc_deps_e *tgt_edge;

  if (deps_has_sec_edge (deps, src_sec, tgt_sec))
    return;

  src_sec_deps = xtensa_get_section_deps (deps, src_sec);
  if (src_sec_deps == NULL)
    {
      /* Add a section.  */
      src_sec_deps = xmalloc (sizeof (reloc_deps_section));
      memset (src_sec_deps, 0, sizeof (reloc_deps_section));
      src_sec_deps->is_only_literal = 0;
      src_sec_deps->preds = NULL;
      src_sec_deps->succs = NULL;
      xtensa_set_section_deps (deps, src_sec, src_sec_deps);
      xtensa_append_section_deps (deps, src_sec);
    }

  tgt_sec_deps = xtensa_get_section_deps (deps, tgt_sec);
  if (tgt_sec_deps == NULL)
    {
      /* Add a section.  */
      tgt_sec_deps = xmalloc (sizeof (reloc_deps_section));
      memset (tgt_sec_deps, 0, sizeof (reloc_deps_section));
      tgt_sec_deps->is_only_literal = 0;
      tgt_sec_deps->preds = NULL;
      tgt_sec_deps->succs = NULL;
      xtensa_set_section_deps (deps, tgt_sec, tgt_sec_deps);
      xtensa_append_section_deps (deps, tgt_sec);
    }

  /* Add the edges.  */
  src_edge = xmalloc (sizeof (reloc_deps_e));
  memset (src_edge, 0, sizeof (reloc_deps_e));
  src_edge->src = src_sec;
  src_edge->tgt = tgt_sec;
  src_edge->next = src_sec_deps->succs;
  src_sec_deps->succs = src_edge;

  tgt_edge = xmalloc (sizeof (reloc_deps_e));
  memset (tgt_edge, 0, sizeof (reloc_deps_e));
  tgt_edge->src = src_sec;
  tgt_edge->tgt = tgt_sec;
  tgt_edge->next = tgt_sec_deps->preds;
  tgt_sec_deps->preds = tgt_edge;
}


static void
build_deps_graph_callback (asection *src_sec,
			   bfd_vma src_offset ATTRIBUTE_UNUSED,
			   asection *target_sec,
			   bfd_vma target_offset ATTRIBUTE_UNUSED,
			   void *closure)
{
  reloc_deps_graph *deps = closure;

  /* If the target is defined.  */
  if (target_sec != NULL)
    add_deps_edge (deps, src_sec, target_sec);
}


static reloc_deps_graph *
ld_build_required_section_dependence (lang_statement_union_type *s)
{
  reloc_deps_graph *deps;
  xtensa_ld_iter_stack *stack = NULL;

  deps = xmalloc (sizeof (reloc_deps_graph));
  deps->sections = NULL;
  deps->count = 0;
  deps->size = 0;

  for (iter_stack_create (&stack, s);
       !iter_stack_empty (&stack);
       iter_stack_next (&stack))
    {
      lang_statement_union_type *l = iter_stack_current (&stack);

      if (l == NULL && link_info.non_contiguous_regions)
	einfo (_("%F%P: Relaxation not supported with "
		 "--enable-non-contiguous-regions.\n"));

      if (l->header.type == lang_input_section_enum)
	{
	  lang_input_section_type *input;
	  input = &l->input_section;
	  xtensa_callback_required_dependence (input->section->owner,
					       input->section,
					       &link_info,
					       /* Use the same closure.  */
					       build_deps_graph_callback,
					       deps);
	}
    }
  return deps;
}


#if EXTRA_VALIDATION
static size_t
ld_count_children (lang_statement_union_type *s)
{
  size_t count = 0;
  xtensa_ld_iter_stack *stack = NULL;
  for (iter_stack_create (&stack, s);
       !iter_stack_empty (&stack);
       iter_stack_next (&stack))
    {
      lang_statement_union_type *l = iter_stack_current (&stack);
      ASSERT (l != NULL);
      count++;
    }
  return count;
}
#endif /* EXTRA_VALIDATION */


/* Check if a particular section is included in the link.  This will only
   be true for one instance of a particular linkonce section.  */

static bool input_section_found = false;
static asection *input_section_target = NULL;

static void
input_section_linked_worker (lang_statement_union_type *statement)
{
  if ((statement->header.type == lang_input_section_enum
       && (statement->input_section.section == input_section_target)))
    input_section_found = true;
}

static bool
input_section_linked (asection *sec)
{
  input_section_found = false;
  input_section_target = sec;
  lang_for_each_statement_worker (input_section_linked_worker, stat_ptr->head);
  return input_section_found;
}


/* Strip out any linkonce property tables or XCC exception tables where the
   associated linkonce text is from a different object file.  Normally,
   a matching set of linkonce sections is taken from the same object file,
   but sometimes the files are compiled differently so that some of the
   linkonce sections are not present in all files.  Stripping the
   inconsistent sections like this is not completely robust -- a much
   better solution is to use comdat groups.  */

static int linkonce_len = sizeof (".gnu.linkonce.") - 1;

static bool
is_inconsistent_linkonce_section (asection *sec)
{
  bfd *abfd = sec->owner;
  const char *sec_name = bfd_section_name (sec);
  const char *name;

  if ((bfd_section_flags (sec) & SEC_LINK_ONCE) == 0
      || strncmp (sec_name, ".gnu.linkonce.", linkonce_len) != 0)
    return false;

  /* Check if this is an Xtensa property section or an exception table
     for Tensilica's XCC compiler.  */
  name = sec_name + linkonce_len;
  if (startswith (name, "prop."))
    name = strchr (name + 5, '.') ? strchr (name + 5, '.') + 1 : name + 5;
  else if (name[1] == '.'
	   && (name[0] == 'p' || name[0] == 'e' || name[0] == 'h'))
    name += 2;
  else
    name = 0;

  if (name)
    {
      char *dep_sec_name = xmalloc (strlen (sec_name) + 1);
      asection *dep_sec;

      /* Get the associated linkonce text section and check if it is
	 included in the link.  If not, this section is inconsistent
	 and should be stripped.  */
      strcpy (dep_sec_name, ".gnu.linkonce.t.");
      strcat (dep_sec_name, name);
      dep_sec = bfd_get_section_by_name (abfd, dep_sec_name);
      if (dep_sec == NULL || ! input_section_linked (dep_sec))
	{
	  free (dep_sec_name);
	  return true;
	}
      free (dep_sec_name);
    }

  return false;
}


static void
xtensa_strip_inconsistent_linkonce_sections (lang_statement_list_type *slist)
{
  lang_statement_union_type **s_p = &slist->head;
  while (*s_p)
    {
      lang_statement_union_type *s = *s_p;
      lang_statement_union_type *s_next = (*s_p)->header.next;

      switch (s->header.type)
	{
	case lang_input_section_enum:
	  if (is_inconsistent_linkonce_section (s->input_section.section))
	    {
	      s->input_section.section->output_section = bfd_abs_section_ptr;
	      *s_p = s_next;
	      continue;
	    }
	  break;

	case lang_constructors_statement_enum:
	  xtensa_strip_inconsistent_linkonce_sections (&constructor_list);
	  break;

	case lang_output_section_statement_enum:
	  if (s->output_section_statement.children.head)
	    xtensa_strip_inconsistent_linkonce_sections
	      (&s->output_section_statement.children);
	  break;

	case lang_wild_statement_enum:
	  xtensa_strip_inconsistent_linkonce_sections
	    (&s->wild_statement.children);
	  break;

	case lang_group_statement_enum:
	  xtensa_strip_inconsistent_linkonce_sections
	    (&s->group_statement.children);
	  break;

	case lang_data_statement_enum:
	case lang_reloc_statement_enum:
	case lang_object_symbols_statement_enum:
	case lang_output_statement_enum:
	case lang_target_statement_enum:
	case lang_input_statement_enum:
	case lang_assignment_statement_enum:
	case lang_padding_statement_enum:
	case lang_address_statement_enum:
	case lang_fill_statement_enum:
	  break;

	default:
	  FAIL ();
	  break;
	}

      s_p = &(*s_p)->header.next;
    }

  /* Reset the tail of the list, in case the last entry was removed.  */
  if (s_p != slist->tail)
    slist->tail = s_p;
}


static void
xtensa_wild_group_interleave_callback (lang_statement_union_type *statement)
{
  lang_wild_statement_type *w;
  reloc_deps_graph *deps;
  if (statement->header.type == lang_wild_statement_enum)
    {
#if EXTRA_VALIDATION
      size_t old_child_count;
      size_t new_child_count;
#endif
      bool no_reorder;

      w = &statement->wild_statement;

      no_reorder = false;

      /* If it has 0 or 1 section bound, then do not reorder.  */
      if (w->children.head == NULL
	  || (w->children.head->header.type == lang_input_section_enum
	      && w->children.head->header.next == NULL))
	no_reorder = true;

      if (w->filenames_sorted)
	no_reorder = true;

      /* Check for sorting in a section list wildcard spec as well.  */
      if (!no_reorder)
	{
	  struct wildcard_list *l;
	  for (l = w->section_list; l != NULL; l = l->next)
	    {
	      if (l->spec.sorted == by_name)
		{
		  no_reorder = true;
		  break;
		}
	    }
	}

      /* Special case until the NOREORDER linker directive is supported:
	 *(.init) output sections and *(.fini) specs may NOT be reordered.  */

      /* Check for sorting in a section list wildcard spec as well.  */
      if (!no_reorder)
	{
	  struct wildcard_list *l;
	  for (l = w->section_list; l != NULL; l = l->next)
	    {
	      if (l->spec.name
		  && ((strcmp (".init", l->spec.name) == 0)
		      || (strcmp (".fini", l->spec.name) == 0)))
		{
		  no_reorder = true;
		  break;
		}
	    }
	}

#if EXTRA_VALIDATION
      old_child_count = ld_count_children (statement);
#endif

      /* It is now officially a target.  Build the graph of source
	 section -> target section (kept as a list of edges).  */
      deps = ld_build_required_section_dependence (statement);

      /* If this wildcard does not reorder....  */
      if (!no_reorder && deps->count != 0)
	{
	  /* First check for reverse dependences.  Fix if possible.  */
	  xtensa_layout_wild (deps, w);

	  xtensa_move_dependencies_to_front (deps, w);
#if EXTRA_VALIDATION
	  new_child_count = ld_count_children (statement);
	  ASSERT (new_child_count == old_child_count);
#endif

	  xtensa_colocate_literals (deps, statement);

#if EXTRA_VALIDATION
	  new_child_count = ld_count_children (statement);
	  ASSERT (new_child_count == old_child_count);
#endif
	}

      /* Clean up.  */
      free_reloc_deps_graph (deps);
    }
}


static void
xtensa_wild_group_interleave (lang_statement_union_type *s)
{
  lang_for_each_statement_worker (xtensa_wild_group_interleave_callback, s);
}


static void
xtensa_layout_wild (const reloc_deps_graph *deps, lang_wild_statement_type *w)
{
  /* If it does not fit initially, we need to do this step.  Move all
     of the wild literal sections to a new list, then move each of
     them back in just before the first section they depend on.  */
  lang_statement_union_type **s_p;
#if EXTRA_VALIDATION
  size_t old_count, new_count;
  size_t ct1, ct2;
#endif

  lang_wild_statement_type literal_wild;
  literal_wild.header.next = NULL;
  literal_wild.header.type = lang_wild_statement_enum;
  literal_wild.filename = NULL;
  literal_wild.filenames_sorted = false;
  literal_wild.section_list = NULL;
  literal_wild.keep_sections = false;
  literal_wild.children.head = NULL;
  literal_wild.children.tail = &literal_wild.children.head;

#if EXTRA_VALIDATION
  old_count = ld_count_children ((lang_statement_union_type*) w);
#endif

  s_p = &w->children.head;
  while (*s_p != NULL)
    {
      lang_statement_union_type *l = *s_p;
      if (l->header.type == lang_input_section_enum)
	{
	  if (section_is_target (deps, l)
	      && ! section_is_source (deps, l))
	    {
	      /* Detach.  */
	      *s_p = l->header.next;
	      if (*s_p == NULL)
		w->children.tail = s_p;
	      l->header.next = NULL;

	      /* Append.  */
	      *literal_wild.children.tail = l;
	      literal_wild.children.tail = &l->header.next;
	      continue;
	    }
	}
      s_p = &(*s_p)->header.next;
    }

#if EXTRA_VALIDATION
  ct1 = ld_count_children ((lang_statement_union_type*) w);
  ct2 = ld_count_children ((lang_statement_union_type*) &literal_wild);

  ASSERT (old_count == (ct1 + ct2));
#endif

  /* Now place them back in front of their dependent sections.  */

  while (literal_wild.children.head != NULL)
    {
      lang_statement_union_type *lit = literal_wild.children.head;
      bool placed = false;

#if EXTRA_VALIDATION
      ASSERT (ct2 > 0);
      ct2--;
#endif

      /* Detach.  */
      literal_wild.children.head = lit->header.next;
      if (literal_wild.children.head == NULL)
	literal_wild.children.tail = &literal_wild.children.head;
      lit->header.next = NULL;

      /* Find a spot to place it.  */
      for (s_p = &w->children.head; *s_p != NULL; s_p = &(*s_p)->header.next)
	{
	  lang_statement_union_type *src = *s_p;
	  if (deps_has_edge (deps, src, lit))
	    {
	      /* Place it here.  */
	      lit->header.next = *s_p;
	      *s_p = lit;
	      placed = true;
	      break;
	    }
	}

      if (!placed)
	{
	  /* Put it at the end.  */
	  *w->children.tail = lit;
	  w->children.tail = &lit->header.next;
	}
    }

#if EXTRA_VALIDATION
  new_count = ld_count_children ((lang_statement_union_type*) w);
  ASSERT (new_count == old_count);
#endif
}


static void
xtensa_colocate_output_literals_callback (lang_statement_union_type *statement)
{
  reloc_deps_graph *deps;
  if (statement->header.type == lang_output_section_statement_enum)
    {
      /* Now, we walk over the contours of the output section statement.

	 First we build the literal section dependences as before.

	 At the first uniquely_literal section, we mark it as a good
	 spot to place other literals.  Continue walking (and counting
	 sizes) until we find the next literal section.  If this
	 section can be moved to the first one, then we move it.  If
	 we every find a modification of ".", start over.  If we find
	 a labeling of the current location, start over.  Finally, at
	 the end, if we require page alignment, add page alignments.  */

#if EXTRA_VALIDATION
      size_t old_child_count;
      size_t new_child_count;
#endif
      bool no_reorder = false;

#if EXTRA_VALIDATION
      old_child_count = ld_count_children (statement);
#endif

      /* It is now officially a target.  Build the graph of source
	 section -> target section (kept as a list of edges).  */

      deps = ld_build_required_section_dependence (statement);

      /* If this wildcard does not reorder....  */
      if (!no_reorder)
	{
	  /* First check for reverse dependences.  Fix if possible.  */
	  xtensa_colocate_literals (deps, statement);

#if EXTRA_VALIDATION
	  new_child_count = ld_count_children (statement);
	  ASSERT (new_child_count == old_child_count);
#endif
	}

      /* Insert align/offset assignment statement.  */
      if (xtensa_use_literal_pages)
	{
	  ld_xtensa_insert_page_offsets (0, statement, deps,
					 xtensa_use_literal_pages);
	  lang_for_each_statement_worker (xtensa_ldlang_clear_addresses,
					  statement);
	}

      /* Clean up.  */
      free_reloc_deps_graph (deps);
    }
}


static void
xtensa_colocate_output_literals (lang_statement_union_type *s)
{
  lang_for_each_statement_worker (xtensa_colocate_output_literals_callback, s);
}


static void
xtensa_ldlang_clear_addresses (lang_statement_union_type *statement)
{
  switch (statement->header.type)
    {
    case lang_input_section_enum:
      {
	asection *bfd_section = statement->input_section.section;
	bfd_section->output_offset = 0;
      }
      break;
    default:
      break;
    }
}


static bfd_vma
ld_assign_relative_paged_dot (bfd_vma dot,
			      lang_statement_union_type *s,
			      const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
			      bool lit_align)
{
  /* Walk through all of the input statements in this wild statement
     assign dot to all of them.  */

  xtensa_ld_iter_stack *stack = NULL;
  xtensa_ld_iter_stack **stack_p = &stack;

  bool first_section = false;
  bool in_literals = false;

  for (iter_stack_create (stack_p, s);
       !iter_stack_empty (stack_p);
       iter_stack_next (stack_p))
    {
      lang_statement_union_type *l = iter_stack_current (stack_p);

      switch (l->header.type)
	{
	case lang_input_section_enum:
	  {
	    asection *section = l->input_section.section;
	    size_t align_pow = section->alignment_power;
	    bool do_xtensa_alignment = false;

	    if (lit_align)
	      {
		bool sec_is_target = section_is_target (deps, l);
		bool sec_is_source = section_is_source (deps, l);

		if (section->size != 0
		    && (first_section
			|| (in_literals && !sec_is_target)
			|| (!in_literals && sec_is_target)))
		  {
		    do_xtensa_alignment = true;
		  }
		first_section = false;
		if (section->size != 0)
		  in_literals = (sec_is_target && !sec_is_source);
	      }

	    if (do_xtensa_alignment && xtensa_page_power != 0)
	      dot += (1 << xtensa_page_power);

	    dot = align_power (dot, align_pow);
	    section->output_offset = dot;
	    dot += section->size;
	  }
	  break;
	case lang_fill_statement_enum:
	  dot += l->fill_statement.size;
	  break;
	case lang_padding_statement_enum:
	  dot += l->padding_statement.size;
	  break;
	default:
	  break;
	}
    }
  return dot;
}


static bool
ld_local_file_relocations_fit (lang_statement_union_type *statement,
			       const reloc_deps_graph *deps ATTRIBUTE_UNUSED)
{
  /* Walk over all of the dependencies that we identified and make
     sure that IF the source and target are here (addr != 0):
     1) target addr < source addr
     2) (roundup(source + source_size, 4) - rounddown(target, 4))
        < (256K - (1 << bad align))
     Need a worst-case proof....  */

  xtensa_ld_iter_stack *stack = NULL;
  xtensa_ld_iter_stack **stack_p = &stack;
  size_t max_align_power = 0;
  size_t align_penalty = 256;
  reloc_deps_e *e;
  size_t i;

  /* Find the worst-case alignment requirement for this set of statements.  */
  for (iter_stack_create (stack_p, statement);
       !iter_stack_empty (stack_p);
       iter_stack_next (stack_p))
    {
      lang_statement_union_type *l = iter_stack_current (stack_p);
      if (l->header.type == lang_input_section_enum)
	{
	  lang_input_section_type *input = &l->input_section;
	  asection *section = input->section;
	  if (section->alignment_power > max_align_power)
	    max_align_power = section->alignment_power;
	}
    }

  /* Now check that everything fits.  */
  for (i = 0; i < deps->count; i++)
    {
      asection *sec = deps->sections[i];
      const reloc_deps_section *deps_section =
	xtensa_get_section_deps (deps, sec);
      if (deps_section)
	{
	  /* We choose to walk through the successors.  */
	  for (e = deps_section->succs; e != NULL; e = e->next)
	    {
	      if (e->src != e->tgt
		  && e->src->output_section == e->tgt->output_section
		  && e->src->output_offset != 0
		  && e->tgt->output_offset != 0)
		{
		  bfd_vma l32r_addr =
		    align_power (e->src->output_offset + e->src->size, 2);
		  bfd_vma target_addr = e->tgt->output_offset & ~3;
		  if (l32r_addr < target_addr)
		    {
		      fflush (stdout);
		      fprintf (stderr, "Warning: "
			       "l32r target section before l32r\n");
		      fflush (stderr);
		      return false;
		    }

		  if (l32r_addr - target_addr > 256 * 1024 - align_penalty)
		    return false;
		}
	    }
	}
    }

  return true;
}


static bfd_vma
ld_xtensa_insert_page_offsets (bfd_vma dot,
			       lang_statement_union_type *s,
			       reloc_deps_graph *deps,
			       bool lit_align)
{
  xtensa_ld_iter_stack *stack = NULL;
  xtensa_ld_iter_stack **stack_p = &stack;

  bool first_section = false;
  bool in_literals = false;

  if (!lit_align)
    return false;

  for (iter_stack_create (stack_p, s);
       !iter_stack_empty (stack_p);
       iter_stack_next (stack_p))
    {
      lang_statement_union_type *l = iter_stack_current (stack_p);

      switch (l->header.type)
	{
	case lang_input_section_enum:
	  {
	    asection *section = l->input_section.section;
	    bool do_xtensa_alignment = false;

	    if (lit_align)
	      {
		if (section->size != 0
		    && (first_section
			|| (in_literals && !section_is_target (deps, l))
			|| (!in_literals && section_is_target (deps, l))))
		  {
		    do_xtensa_alignment = true;
		  }
		first_section = false;
		if (section->size != 0)
		  {
		    in_literals = (section_is_target (deps, l)
				   && !section_is_source (deps, l));
		  }
	      }

	    if (do_xtensa_alignment && xtensa_page_power != 0)
	      {
		/* Create an expression that increments the current address,
		   i.e., "dot", by (1 << xtensa_align_power).  */
		etree_type *name_op = exp_nameop (NAME, ".");
		etree_type *addend_op = exp_intop (1 << xtensa_page_power);
		etree_type *add_op = exp_binop ('+', name_op, addend_op);
		etree_type *assign_op = exp_assign (".", add_op, false);

		lang_assignment_statement_type *assign_stmt;
		lang_statement_union_type *assign_union;
		lang_statement_list_type tmplist;

		/* There is hidden state in "lang_add_assignment".  It
		   appends the new assignment statement to the stat_ptr
		   list.  Thus, we swap it before and after the call.  */

		lang_list_init (&tmplist);
		push_stat_ptr (&tmplist);
		/* Warning: side effect; statement appended to stat_ptr.  */
		assign_stmt = lang_add_assignment (assign_op);
		assign_union = (lang_statement_union_type *) assign_stmt;
		pop_stat_ptr ();

		assign_union->header.next = l;
		*(*stack_p)->iterloc.loc = assign_union;
		iter_stack_next (stack_p);
	      }
	  }
	  break;
	default:
	  break;
	}
    }
  return dot;
}

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_OPT_SIZEOPT              (300)
#define OPTION_LITERAL_MOVEMENT		(OPTION_OPT_SIZEOPT + 1)
#define OPTION_NO_LITERAL_MOVEMENT	(OPTION_LITERAL_MOVEMENT + 1)
#define OPTION_ABI_WINDOWED		(OPTION_NO_LITERAL_MOVEMENT + 1)
#define OPTION_ABI_CALL0		(OPTION_ABI_WINDOWED + 1)
extern int elf32xtensa_size_opt;
extern int elf32xtensa_no_literal_movement;
extern int elf32xtensa_abi;
'

PARSE_AND_LIST_LONGOPTS='
  { "size-opt", no_argument, NULL, OPTION_OPT_SIZEOPT},
  { "literal-movement", no_argument, NULL, OPTION_LITERAL_MOVEMENT},
  { "no-literal-movement", no_argument, NULL, OPTION_NO_LITERAL_MOVEMENT},
  { "abi-windowed", no_argument, NULL, OPTION_ABI_WINDOWED},
  { "abi-call0", no_argument, NULL, OPTION_ABI_CALL0},
'

PARSE_AND_LIST_OPTIONS='
  fprintf (file, _("\
  --size-opt                  When relaxing longcalls, prefer size\n\
                                optimization over branch target alignment\n"));
  fprintf (file, _("\
  --abi-windowed              Choose windowed ABI for the output object\n"));
  fprintf (file, _("\
  --abi-call0                 Choose call0 ABI for the output object\n"));
'

PARSE_AND_LIST_ARGS_CASES='
    case OPTION_OPT_SIZEOPT:
      elf32xtensa_size_opt = 1;
      break;
    case OPTION_LITERAL_MOVEMENT:
      elf32xtensa_no_literal_movement = 0;
      break;
    case OPTION_NO_LITERAL_MOVEMENT:
      elf32xtensa_no_literal_movement = 1;
      break;
    case OPTION_ABI_WINDOWED:
      elf32xtensa_abi = XTHAL_ABI_WINDOWED;
      break;
    case OPTION_ABI_CALL0:
      elf32xtensa_abi = XTHAL_ABI_CALL0;
      break;
'

# Replace some of the standard ELF functions with our own versions.
#
LDEMUL_BEFORE_PARSE=elf_xtensa_before_parse
LDEMUL_AFTER_OPEN=elf_xtensa_after_open
LDEMUL_CHOOSE_TARGET=elf_xtensa_choose_target
LDEMUL_BEFORE_ALLOCATION=elf_xtensa_before_allocation
