# This shell script emits a C file. -*- C -*-
#   Copyright (C) 2003-2018 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 elf32.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 XSHAL_ABI
#define XSHAL_ABI 0
#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 bfd_boolean xtensa_use_literal_pages = FALSE;

#define EXTRA_VALIDATION 0


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 bfd_boolean
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_get_section_flags (abfd, insn_sec));
  if (prop_sec == NULL
      || ! bfd_set_section_alignment (abfd, 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);

  if (insn_contents)
    free (insn_contents);

  return TRUE;

 cleanup:
  if (prop_sec && prop_sec->owner)
    remove_section (abfd, prop_sec);
  if (insn_contents)
    free (insn_contents);
  if (internal_relocs)
    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_get_section_name (abfd, 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 (CONST_STRNEQ (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 %B (%s); subsequent disassembly may be incomplete\n"),
		 insn_sec_name, abfd, message);
	}
    }
  if (owned_prop_sec_name)
    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 bfd_boolean
xt_config_info_unpack_and_check (char *data,
				 bfd_boolean *pmismatch,
				 char **pmsg)
{
  char *d, *key;
  unsigned 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 (num != XSHAL_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 = "";
  bfd_boolean mismatch;

  data = xmalloc (info_sec->size);
  if (! bfd_get_section_contents (abfd, info_sec, data, 0, info_sec->size))
    einfo (_("%F%P:%B: cannot read contents of section %A\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:%B: warning: incompatible Xtensa configuration (%s)\n"),
	       abfd, errmsg);
    }
  else
    einfo (_("%P:%B: 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;
  bfd_boolean 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 %B 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, XSHAL_ABI);
      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;
  bfd_boolean 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 bfd_boolean 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 bfd_boolean 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 *,
   bfd_boolean);
static bfd_vma ld_xtensa_insert_page_offsets
  (bfd_vma, lang_statement_union_type *, reloc_deps_graph *, bfd_boolean);
#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.  */
  reloc_deps_section *sec_deps = sec->userdata;
  return sec_deps;
}

static void
xtensa_set_section_deps (const reloc_deps_graph *deps ATTRIBUTE_UNUSED,
			 asection *sec,
			 reloc_deps_section *deps_section)
{
  sec->userdata = 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];
	}
      if (deps->sections != NULL)
	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);
    }
  if (deps->sections)
    free (deps->sections);

  free (deps);
}


static bfd_boolean
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 bfd_boolean
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 bfd_boolean
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 bfd_boolean
iter_stack_empty (xtensa_ld_iter_stack **stack_p)
{
  return *stack_p == NULL;
}


static bfd_boolean
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;
  bfd_boolean in_literals = FALSE;

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

  iter_stack_create (stack_p, statement);

  while (!iter_stack_empty (stack_p))
    {
      bfd_boolean 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
	    {
	      bfd_boolean 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 bfd_boolean
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 bfd_boolean
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->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 bfd_boolean 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 bfd_boolean
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 bfd_boolean
is_inconsistent_linkonce_section (asection *sec)
{
  bfd *abfd = sec->owner;
  const char *sec_name = bfd_get_section_name (abfd, sec);
  const char *name;

  if ((bfd_get_section_flags (abfd, 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 (CONST_STRNEQ (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
      bfd_boolean 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;
      bfd_boolean 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
      bfd_boolean 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,
			      bfd_boolean 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;

  bfd_boolean first_section = FALSE;
  bfd_boolean 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;
	    bfd_boolean do_xtensa_alignment = FALSE;

	    if (lit_align)
	      {
		bfd_boolean sec_is_target = section_is_target (deps, l);
		bfd_boolean 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 bfd_boolean
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,
			       bfd_boolean lit_align)
{
  xtensa_ld_iter_stack *stack = NULL;
  xtensa_ld_iter_stack **stack_p = &stack;

  bfd_boolean first_section = FALSE;
  bfd_boolean 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;
	    bfd_boolean 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)
extern int elf32xtensa_size_opt;
extern int elf32xtensa_no_literal_movement;
'

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},
'

PARSE_AND_LIST_OPTIONS='
  fprintf (file, _("\
  --size-opt                  When relaxing longcalls, prefer size\n\
                                optimization over branch target alignment\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;
'

# 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
