/* Xtensa-specific support for 32-bit ELF.
   Copyright 2003, 2004 Free Software Foundation, Inc.

   This file is part of BFD, the Binary File Descriptor library.

   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 2 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., 59 Temple Place - Suite 330, Boston, MA
   02111-1307, USA.  */

#include "bfd.h"
#include "sysdep.h"

#ifdef ANSI_PROTOTYPES
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include <strings.h>

#include "bfdlink.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/xtensa.h"
#include "xtensa-isa.h"
#include "xtensa-config.h"

#define XTENSA_NO_NOP_REMOVAL 0

/* Local helper functions.  */

static bfd_boolean add_extra_plt_sections (bfd *, int);
static char *build_encoding_error_message (xtensa_opcode, bfd_vma);
static bfd_reloc_status_type bfd_elf_xtensa_reloc
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_boolean do_fix_for_relocatable_link
  (Elf_Internal_Rela *, bfd *, asection *, bfd_byte *);
static void do_fix_for_final_link
  (Elf_Internal_Rela *, bfd *, asection *, bfd_byte *, bfd_vma *);

/* Local functions to handle Xtensa configurability.  */

static bfd_boolean is_indirect_call_opcode (xtensa_opcode);
static bfd_boolean is_direct_call_opcode (xtensa_opcode);
static bfd_boolean is_windowed_call_opcode (xtensa_opcode);
static xtensa_opcode get_const16_opcode (void);
static xtensa_opcode get_l32r_opcode (void);
static bfd_vma l32r_offset (bfd_vma, bfd_vma);
static int get_relocation_opnd (xtensa_opcode, int);
static int get_relocation_slot (int);
static xtensa_opcode get_relocation_opcode
  (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *);
static bfd_boolean is_l32r_relocation
  (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *);
static bfd_boolean is_alt_relocation (int);
static bfd_boolean is_operand_relocation (int);
static bfd_size_type insn_decode_len
  (bfd_byte *, bfd_size_type, bfd_size_type);
static xtensa_opcode insn_decode_opcode
  (bfd_byte *, bfd_size_type, bfd_size_type, int);
static bfd_boolean check_branch_target_aligned
  (bfd_byte *, bfd_size_type, bfd_vma, bfd_vma);
static bfd_boolean check_loop_aligned
  (bfd_byte *, bfd_size_type, bfd_vma, bfd_vma);
static bfd_boolean check_branch_target_aligned_address (bfd_vma, int);
static bfd_size_type get_asm_simplify_size
  (bfd_byte *, bfd_size_type, bfd_size_type);

/* Functions for link-time code simplifications.  */

static bfd_reloc_status_type elf_xtensa_do_asm_simplify
  (bfd_byte *, bfd_vma, bfd_vma, char **);
static bfd_reloc_status_type contract_asm_expansion
  (bfd_byte *, bfd_vma, Elf_Internal_Rela *, char **);
static xtensa_opcode swap_callx_for_call_opcode (xtensa_opcode);
static xtensa_opcode get_expanded_call_opcode (bfd_byte *, int, bfd_boolean *);

/* Access to internal relocations, section contents and symbols.  */

static Elf_Internal_Rela *retrieve_internal_relocs
  (bfd *, asection *, bfd_boolean);
static void pin_internal_relocs (asection *, Elf_Internal_Rela *);
static void release_internal_relocs (asection *, Elf_Internal_Rela *);
static bfd_byte *retrieve_contents (bfd *, asection *, bfd_boolean);
static void pin_contents (asection *, bfd_byte *);
static void release_contents (asection *, bfd_byte *);
static Elf_Internal_Sym *retrieve_local_syms (bfd *);

/* Miscellaneous utility functions.  */

static asection *elf_xtensa_get_plt_section (bfd *, int);
static asection *elf_xtensa_get_gotplt_section (bfd *, int);
static asection *get_elf_r_symndx_section (bfd *, unsigned long);
static struct elf_link_hash_entry *get_elf_r_symndx_hash_entry
  (bfd *, unsigned long);
static bfd_vma get_elf_r_symndx_offset (bfd *, unsigned long);
static bfd_boolean is_reloc_sym_weak (bfd *, Elf_Internal_Rela *);
static bfd_boolean pcrel_reloc_fits (xtensa_opcode, int, bfd_vma, bfd_vma);
static bfd_boolean xtensa_is_property_section (asection *);
static bfd_boolean xtensa_is_littable_section (asection *);
static int internal_reloc_compare (const void *, const void *);
static int internal_reloc_matches (const void *, const void *);
extern char *xtensa_get_property_section_name (asection *, const char *);
static flagword xtensa_get_property_predef_flags (asection *);

/* Other functions called directly by the linker.  */

typedef void (*deps_callback_t)
  (asection *, bfd_vma, asection *, bfd_vma, void *);
extern bfd_boolean xtensa_callback_required_dependence
  (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *);


/* Globally visible flag for choosing size optimization of NOP removal
   instead of branch-target-aware minimization for NOP removal.
   When nonzero, narrow all instructions and remove all NOPs possible
   around longcall expansions.  */

int elf32xtensa_size_opt;


/* The "new_section_hook" is used to set up a per-section
   "xtensa_relax_info" data structure with additional information used
   during relaxation.  */

typedef struct xtensa_relax_info_struct xtensa_relax_info;


/* Total count of PLT relocations seen during check_relocs.
   The actual PLT code must be split into multiple sections and all
   the sections have to be created before size_dynamic_sections,
   where we figure out the exact number of PLT entries that will be
   needed.  It is OK if this count is an overestimate, e.g., some
   relocations may be removed by GC.  */

static int plt_reloc_count = 0;


/* The GNU tools do not easily allow extending interfaces to pass around
   the pointer to the Xtensa ISA information, so instead we add a global
   variable here (in BFD) that can be used by any of the tools that need
   this information. */

xtensa_isa xtensa_default_isa;


/* When this is true, relocations may have been modified to refer to
   symbols from other input files.  The per-section list of "fix"
   records needs to be checked when resolving relocations.  */

static bfd_boolean relaxing_section = FALSE;

/* When this is true, during final links, literals that cannot be
   coalesced and their relocations may be moved to other sections.  */

int elf32xtensa_no_literal_movement = 1;


static reloc_howto_type elf_howto_table[] =
{
  HOWTO (R_XTENSA_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_NONE",
	 FALSE, 0x00000000, 0x00000000, FALSE),
  HOWTO (R_XTENSA_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
	 bfd_elf_xtensa_reloc, "R_XTENSA_32",
	 TRUE, 0xffffffff, 0xffffffff, FALSE),
  /* Replace a 32-bit value with a value from the runtime linker (only
     used by linker-generated stub functions).  The r_addend value is
     special: 1 means to substitute a pointer to the runtime linker's
     dynamic resolver function; 2 means to substitute the link map for
     the shared object.  */
  HOWTO (R_XTENSA_RTLD, 0, 2, 32, FALSE, 0, complain_overflow_dont,
	 NULL, "R_XTENSA_RTLD",
	 FALSE, 0x00000000, 0x00000000, FALSE),
  HOWTO (R_XTENSA_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
	 bfd_elf_generic_reloc, "R_XTENSA_GLOB_DAT",
	 FALSE, 0xffffffff, 0xffffffff, FALSE),
  HOWTO (R_XTENSA_JMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
	 bfd_elf_generic_reloc, "R_XTENSA_JMP_SLOT",
	 FALSE, 0xffffffff, 0xffffffff, FALSE),
  HOWTO (R_XTENSA_RELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
	 bfd_elf_generic_reloc, "R_XTENSA_RELATIVE",
	 FALSE, 0xffffffff, 0xffffffff, FALSE),
  HOWTO (R_XTENSA_PLT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
	 bfd_elf_xtensa_reloc, "R_XTENSA_PLT",
	 FALSE, 0xffffffff, 0xffffffff, FALSE),
  EMPTY_HOWTO (7),
  HOWTO (R_XTENSA_OP0, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_OP0",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_OP1, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_OP1",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_OP2, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_OP2",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  /* Assembly auto-expansion.  */
  HOWTO (R_XTENSA_ASM_EXPAND, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_ASM_EXPAND",
	 FALSE, 0x00000000, 0x00000000, FALSE),
  /* Relax assembly auto-expansion.  */
  HOWTO (R_XTENSA_ASM_SIMPLIFY, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_ASM_SIMPLIFY",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  EMPTY_HOWTO (13),
  EMPTY_HOWTO (14),
  /* GNU extension to record C++ vtable hierarchy.  */
  HOWTO (R_XTENSA_GNU_VTINHERIT, 0, 2, 0, FALSE, 0, complain_overflow_dont,
         NULL, "R_XTENSA_GNU_VTINHERIT",
	 FALSE, 0x00000000, 0x00000000, FALSE),
  /* GNU extension to record C++ vtable member usage.  */
  HOWTO (R_XTENSA_GNU_VTENTRY, 0, 2, 0, FALSE, 0, complain_overflow_dont,
         _bfd_elf_rel_vtable_reloc_fn, "R_XTENSA_GNU_VTENTRY",
	 FALSE, 0x00000000, 0x00000000, FALSE),

  /* Relocations for supporting difference of symbols.  */
  HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8",
	 FALSE, 0xffffffff, 0xffffffff, FALSE),
  HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16",
	 FALSE, 0xffffffff, 0xffffffff, FALSE),
  HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32",
	 FALSE, 0xffffffff, 0xffffffff, FALSE),

  /* General immediate operand relocations.  */
  HOWTO (R_XTENSA_SLOT0_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT1_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT2_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT3_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT4_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT5_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT6_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT7_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT8_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT9_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT10_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT11_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT12_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT13_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT14_OP, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_OP",
	 FALSE, 0x00000000, 0x00000000, TRUE),

  /* "Alternate" relocations.  The meaning of these is opcode-specific.  */
  HOWTO (R_XTENSA_SLOT0_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT0_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT1_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT1_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT2_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT2_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT3_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT3_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT4_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT4_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT5_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT5_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT6_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT6_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT7_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT7_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT8_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT8_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT9_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT9_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT10_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT10_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT11_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT11_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT12_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT12_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT13_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT13_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE),
  HOWTO (R_XTENSA_SLOT14_ALT, 0, 0, 0, TRUE, 0, complain_overflow_dont,
	 bfd_elf_xtensa_reloc, "R_XTENSA_SLOT14_ALT",
	 FALSE, 0x00000000, 0x00000000, TRUE)
};

#if DEBUG_GEN_RELOC
#define TRACE(str) \
  fprintf (stderr, "Xtensa bfd reloc lookup %d (%s)\n", code, str)
#else
#define TRACE(str)
#endif

static reloc_howto_type *
elf_xtensa_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
			      bfd_reloc_code_real_type code)
{
  switch (code)
    {
    case BFD_RELOC_NONE:
      TRACE ("BFD_RELOC_NONE");
      return &elf_howto_table[(unsigned) R_XTENSA_NONE ];

    case BFD_RELOC_32:
      TRACE ("BFD_RELOC_32");
      return &elf_howto_table[(unsigned) R_XTENSA_32 ];

    case BFD_RELOC_XTENSA_DIFF8:
      TRACE ("BFD_RELOC_XTENSA_DIFF8");
      return &elf_howto_table[(unsigned) R_XTENSA_DIFF8 ];

    case BFD_RELOC_XTENSA_DIFF16:
      TRACE ("BFD_RELOC_XTENSA_DIFF16");
      return &elf_howto_table[(unsigned) R_XTENSA_DIFF16 ];

    case BFD_RELOC_XTENSA_DIFF32:
      TRACE ("BFD_RELOC_XTENSA_DIFF32");
      return &elf_howto_table[(unsigned) R_XTENSA_DIFF32 ];

    case BFD_RELOC_XTENSA_RTLD:
      TRACE ("BFD_RELOC_XTENSA_RTLD");
      return &elf_howto_table[(unsigned) R_XTENSA_RTLD ];

    case BFD_RELOC_XTENSA_GLOB_DAT:
      TRACE ("BFD_RELOC_XTENSA_GLOB_DAT");
      return &elf_howto_table[(unsigned) R_XTENSA_GLOB_DAT ];

    case BFD_RELOC_XTENSA_JMP_SLOT:
      TRACE ("BFD_RELOC_XTENSA_JMP_SLOT");
      return &elf_howto_table[(unsigned) R_XTENSA_JMP_SLOT ];

    case BFD_RELOC_XTENSA_RELATIVE:
      TRACE ("BFD_RELOC_XTENSA_RELATIVE");
      return &elf_howto_table[(unsigned) R_XTENSA_RELATIVE ];

    case BFD_RELOC_XTENSA_PLT:
      TRACE ("BFD_RELOC_XTENSA_PLT");
      return &elf_howto_table[(unsigned) R_XTENSA_PLT ];

    case BFD_RELOC_XTENSA_OP0:
      TRACE ("BFD_RELOC_XTENSA_OP0");
      return &elf_howto_table[(unsigned) R_XTENSA_OP0 ];

    case BFD_RELOC_XTENSA_OP1:
      TRACE ("BFD_RELOC_XTENSA_OP1");
      return &elf_howto_table[(unsigned) R_XTENSA_OP1 ];

    case BFD_RELOC_XTENSA_OP2:
      TRACE ("BFD_RELOC_XTENSA_OP2");
      return &elf_howto_table[(unsigned) R_XTENSA_OP2 ];

    case BFD_RELOC_XTENSA_ASM_EXPAND:
      TRACE ("BFD_RELOC_XTENSA_ASM_EXPAND");
      return &elf_howto_table[(unsigned) R_XTENSA_ASM_EXPAND ];

    case BFD_RELOC_XTENSA_ASM_SIMPLIFY:
      TRACE ("BFD_RELOC_XTENSA_ASM_SIMPLIFY");
      return &elf_howto_table[(unsigned) R_XTENSA_ASM_SIMPLIFY ];

    case BFD_RELOC_VTABLE_INHERIT:
      TRACE ("BFD_RELOC_VTABLE_INHERIT");
      return &elf_howto_table[(unsigned) R_XTENSA_GNU_VTINHERIT ];

    case BFD_RELOC_VTABLE_ENTRY:
      TRACE ("BFD_RELOC_VTABLE_ENTRY");
      return &elf_howto_table[(unsigned) R_XTENSA_GNU_VTENTRY ];

    default:
      if (code >= BFD_RELOC_XTENSA_SLOT0_OP
	  && code <= BFD_RELOC_XTENSA_SLOT14_OP)
	{
	  unsigned n = (R_XTENSA_SLOT0_OP +
			(code - BFD_RELOC_XTENSA_SLOT0_OP));
	  return &elf_howto_table[n];
	}

      if (code >= BFD_RELOC_XTENSA_SLOT0_ALT
	  && code <= BFD_RELOC_XTENSA_SLOT14_ALT)
	{
	  unsigned n = (R_XTENSA_SLOT0_ALT +
			(code - BFD_RELOC_XTENSA_SLOT0_ALT));
	  return &elf_howto_table[n];
	}

      break;
    }

  TRACE ("Unknown");
  return NULL;
}


/* Given an ELF "rela" relocation, find the corresponding howto and record
   it in the BFD internal arelent representation of the relocation.  */

static void
elf_xtensa_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
			       arelent *cache_ptr,
			       Elf_Internal_Rela *dst)
{
  unsigned int r_type = ELF32_R_TYPE (dst->r_info);

  BFD_ASSERT (r_type < (unsigned int) R_XTENSA_max);
  cache_ptr->howto = &elf_howto_table[r_type];
}


/* Functions for the Xtensa ELF linker.  */

/* The name of the dynamic interpreter.  This is put in the .interp
   section.  */

#define ELF_DYNAMIC_INTERPRETER "/lib/ld.so"

/* The size in bytes of an entry in the procedure linkage table.
   (This does _not_ include the space for the literals associated with
   the PLT entry.) */

#define PLT_ENTRY_SIZE 16

/* For _really_ large PLTs, we may need to alternate between literals
   and code to keep the literals within the 256K range of the L32R
   instructions in the code.  It's unlikely that anyone would ever need
   such a big PLT, but an arbitrary limit on the PLT size would be bad.
   Thus, we split the PLT into chunks.  Since there's very little
   overhead (2 extra literals) for each chunk, the chunk size is kept
   small so that the code for handling multiple chunks get used and
   tested regularly.  With 254 entries, there are 1K of literals for
   each chunk, and that seems like a nice round number.  */

#define PLT_ENTRIES_PER_CHUNK 254

/* PLT entries are actually used as stub functions for lazy symbol
   resolution.  Once the symbol is resolved, the stub function is never
   invoked.  Note: the 32-byte frame size used here cannot be changed
   without a corresponding change in the runtime linker.  */

static const bfd_byte elf_xtensa_be_plt_entry[PLT_ENTRY_SIZE] =
{
  0x6c, 0x10, 0x04,	/* entry sp, 32 */
  0x18, 0x00, 0x00,	/* l32r  a8, [got entry for rtld's resolver] */
  0x1a, 0x00, 0x00,	/* l32r  a10, [got entry for rtld's link map] */
  0x1b, 0x00, 0x00,	/* l32r  a11, [literal for reloc index] */
  0x0a, 0x80, 0x00,	/* jx    a8 */
  0			/* unused */
};

static const bfd_byte elf_xtensa_le_plt_entry[PLT_ENTRY_SIZE] =
{
  0x36, 0x41, 0x00,	/* entry sp, 32 */
  0x81, 0x00, 0x00,	/* l32r  a8, [got entry for rtld's resolver] */
  0xa1, 0x00, 0x00,	/* l32r  a10, [got entry for rtld's link map] */
  0xb1, 0x00, 0x00,	/* l32r  a11, [literal for reloc index] */
  0xa0, 0x08, 0x00,	/* jx    a8 */
  0			/* unused */
};


static inline bfd_boolean
xtensa_elf_dynamic_symbol_p (struct elf_link_hash_entry *h,
			     struct bfd_link_info *info)
{
  /* Check if we should do dynamic things to this symbol.  The
     "ignore_protected" argument need not be set, because Xtensa code
     does not require special handling of STV_PROTECTED to make function
     pointer comparisons work properly.  The PLT addresses are never
     used for function pointers.  */

  return _bfd_elf_dynamic_symbol_p (h, info, 0);
}


static int
property_table_compare (const void *ap, const void *bp)
{
  const property_table_entry *a = (const property_table_entry *) ap;
  const property_table_entry *b = (const property_table_entry *) bp;

  if (a->address == b->address)
    {
      /* The only circumstance where two entries may legitimately have the
	 same address is when one of them is a zero-size placeholder to
	 mark a place where fill can be inserted.  The zero-size entry should
	 come first.  */
      BFD_ASSERT ((a->size == 0 || b->size == 0));

      if (a->size != b->size)
	return (a->size - b->size);

      if ((a->flags & XTENSA_PROP_ALIGN) != (b->flags & XTENSA_PROP_ALIGN))
	return ((b->flags & XTENSA_PROP_ALIGN)
		- (a->flags & XTENSA_PROP_ALIGN));

      if ((a->flags & XTENSA_PROP_ALIGN)
	  && (GET_XTENSA_PROP_ALIGNMENT (a->flags)
	      != GET_XTENSA_PROP_ALIGNMENT (b->flags)))
	return (GET_XTENSA_PROP_ALIGNMENT (a->flags)
		- GET_XTENSA_PROP_ALIGNMENT (b->flags));
      
      if ((a->flags & XTENSA_PROP_UNREACHABLE)
	  != (b->flags & XTENSA_PROP_UNREACHABLE))
	return ((b->flags & XTENSA_PROP_UNREACHABLE)
		- (a->flags & XTENSA_PROP_UNREACHABLE));

      return (a->flags - b->flags);
    }

  return (a->address - b->address);
}


static int
property_table_matches (const void *ap, const void *bp)
{
  const property_table_entry *a = (const property_table_entry *) ap;
  const property_table_entry *b = (const property_table_entry *) bp;

  /* Check if one entry overlaps with the other.  */
  if ((b->address >= a->address && b->address < (a->address + a->size))
      || (a->address >= b->address && a->address < (b->address + b->size)))
    return 0;

  return (a->address - b->address);
}


/* Get the literal table or property table entries for the given
   section.  Sets TABLE_P and returns the number of entries.  On
   error, returns a negative value.  */

static int
xtensa_read_table_entries (bfd *abfd,
			   asection *section,
			   property_table_entry **table_p,
			   const char *sec_name,
			   bfd_boolean output_addr)
{
  asection *table_section;
  char *table_section_name;
  bfd_size_type table_size = 0;
  bfd_byte *table_data;
  property_table_entry *blocks;
  int block_count;
  bfd_size_type num_records;
  Elf_Internal_Rela *internal_relocs;
  bfd_vma section_addr;
  flagword predef_flags;
  bfd_size_type table_entry_size;

  if (!section
      || !(section->flags & SEC_ALLOC)
      || (section->flags & SEC_DEBUGGING))
    {
      *table_p = NULL;
      return 0;
    }

  table_section_name = xtensa_get_property_section_name (section, sec_name);
  table_section = bfd_get_section_by_name (abfd, table_section_name);
  free (table_section_name);
  if (table_section)
    table_size = table_section->size;

  if (table_size == 0) 
    {
      *table_p = NULL;
      return 0;
    }

  predef_flags = xtensa_get_property_predef_flags (table_section);
  table_entry_size = 12;
  if (predef_flags)
    table_entry_size -= 4;

  num_records = table_size / table_entry_size;
  table_data = retrieve_contents (abfd, table_section, TRUE);
  blocks = (property_table_entry *)
    bfd_malloc (num_records * sizeof (property_table_entry));
  block_count = 0;

  if (output_addr)
    section_addr = section->output_section->vma + section->output_offset;
  else
    section_addr = section->vma;

  /* If the file has not yet been relocated, process the relocations
     and sort out the table entries that apply to the specified section.  */
  internal_relocs = retrieve_internal_relocs (abfd, table_section, TRUE);
  if (internal_relocs && !table_section->reloc_done)
    {
      unsigned i;

      for (i = 0; i < table_section->reloc_count; i++)
	{
	  Elf_Internal_Rela *rel = &internal_relocs[i];
	  unsigned long r_symndx;

	  if (ELF32_R_TYPE (rel->r_info) == R_XTENSA_NONE)
	    continue;

	  BFD_ASSERT (ELF32_R_TYPE (rel->r_info) == R_XTENSA_32);
	  r_symndx = ELF32_R_SYM (rel->r_info);

	  if (get_elf_r_symndx_section (abfd, r_symndx) == section)
	    {
	      bfd_vma sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
	      BFD_ASSERT (sym_off == 0);
	      BFD_ASSERT (rel->r_addend == 0);
	      blocks[block_count].address =
		(section_addr + sym_off + rel->r_addend
		 + bfd_get_32 (abfd, table_data + rel->r_offset));
	      blocks[block_count].size =
		bfd_get_32 (abfd, table_data + rel->r_offset + 4);
	      if (predef_flags)
		blocks[block_count].flags = predef_flags;
	      else
		blocks[block_count].flags =
		  bfd_get_32 (abfd, table_data + rel->r_offset + 8);
	      block_count++;
	    }
	}
    }
  else
    {
      /* The file has already been relocated and the addresses are
	 already in the table.  */
      bfd_vma off;
      bfd_size_type section_limit = bfd_get_section_limit (abfd, section);

      for (off = 0; off < table_size; off += table_entry_size) 
	{
	  bfd_vma address = bfd_get_32 (abfd, table_data + off);

	  if (address >= section_addr
	      && address < section_addr + section_limit)
	    {
	      blocks[block_count].address = address;
	      blocks[block_count].size =
		bfd_get_32 (abfd, table_data + off + 4);
	      if (predef_flags)
		blocks[block_count].flags = predef_flags;
	      else
		blocks[block_count].flags =
		  bfd_get_32 (abfd, table_data + off + 8);
	      block_count++;
	    }
	}
    }

  release_contents (table_section, table_data);
  release_internal_relocs (table_section, internal_relocs);

  if (block_count > 0)
    {
      /* Now sort them into address order for easy reference.  */
      qsort (blocks, block_count, sizeof (property_table_entry),
	     property_table_compare);
    }

  *table_p = blocks;
  return block_count;
}


static property_table_entry *
elf_xtensa_find_property_entry (property_table_entry *property_table,
				int property_table_size,
				bfd_vma addr)
{
  property_table_entry entry;
  property_table_entry *rv;

  if (property_table_size == 0)
    return NULL;

  entry.address = addr;
  entry.size = 1;
  entry.flags = 0;

  rv = bsearch (&entry, property_table, property_table_size,
		sizeof (property_table_entry), property_table_matches);
  return rv;
}


static bfd_boolean
elf_xtensa_in_literal_pool (property_table_entry *lit_table,
			    int lit_table_size,
			    bfd_vma addr)
{
  if (elf_xtensa_find_property_entry (lit_table, lit_table_size, addr))
    return TRUE;

  return FALSE;
}


/* Look through the relocs for a section during the first phase, and
   calculate needed space in the dynamic reloc sections.  */

static bfd_boolean
elf_xtensa_check_relocs (bfd *abfd,
			 struct bfd_link_info *info,
			 asection *sec,
			 const Elf_Internal_Rela *relocs)
{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  const Elf_Internal_Rela *rel;
  const Elf_Internal_Rela *rel_end;

  if (info->relocatable)
    return TRUE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);

  rel_end = relocs + sec->reloc_count;
  for (rel = relocs; rel < rel_end; rel++)
    {
      unsigned int r_type;
      unsigned long r_symndx;
      struct elf_link_hash_entry *h;

      r_symndx = ELF32_R_SYM (rel->r_info);
      r_type = ELF32_R_TYPE (rel->r_info);

      if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
	{
	  (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
				 abfd, r_symndx);
	  return FALSE;
	}

      if (r_symndx < symtab_hdr->sh_info)
	h = NULL;
      else
	{
	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
	  while (h->root.type == bfd_link_hash_indirect
		 || h->root.type == bfd_link_hash_warning)
	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
	}

      switch (r_type)
	{
	case R_XTENSA_32:
	  if (h == NULL)
	    goto local_literal;

	  if ((sec->flags & SEC_ALLOC) != 0)
	    {
	      if (h->got.refcount <= 0)
		h->got.refcount = 1;
	      else
		h->got.refcount += 1;
	    }
	  break;

	case R_XTENSA_PLT:
	  /* If this relocation is against a local symbol, then it's
	     exactly the same as a normal local GOT entry.  */
	  if (h == NULL)
	    goto local_literal;

	  if ((sec->flags & SEC_ALLOC) != 0)
	    {
	      if (h->plt.refcount <= 0)
		{
		  h->needs_plt = 1;
		  h->plt.refcount = 1;
		}
	      else
		h->plt.refcount += 1;

	      /* Keep track of the total PLT relocation count even if we
		 don't yet know whether the dynamic sections will be
		 created.  */
	      plt_reloc_count += 1;

	      if (elf_hash_table (info)->dynamic_sections_created)
		{
		  if (!add_extra_plt_sections (elf_hash_table (info)->dynobj,
					       plt_reloc_count))
		    return FALSE;
		}
	    }
	  break;

	local_literal:
	  if ((sec->flags & SEC_ALLOC) != 0)
	    {
	      bfd_signed_vma *local_got_refcounts;

	      /* This is a global offset table entry for a local symbol.  */
	      local_got_refcounts = elf_local_got_refcounts (abfd);
	      if (local_got_refcounts == NULL)
		{
		  bfd_size_type size;

		  size = symtab_hdr->sh_info;
		  size *= sizeof (bfd_signed_vma);
		  local_got_refcounts =
		    (bfd_signed_vma *) bfd_zalloc (abfd, size);
		  if (local_got_refcounts == NULL)
		    return FALSE;
		  elf_local_got_refcounts (abfd) = local_got_refcounts;
		}
	      local_got_refcounts[r_symndx] += 1;
	    }
	  break;

	case R_XTENSA_OP0:
	case R_XTENSA_OP1:
	case R_XTENSA_OP2:
	case R_XTENSA_SLOT0_OP:
	case R_XTENSA_SLOT1_OP:
	case R_XTENSA_SLOT2_OP:
	case R_XTENSA_SLOT3_OP:
	case R_XTENSA_SLOT4_OP:
	case R_XTENSA_SLOT5_OP:
	case R_XTENSA_SLOT6_OP:
	case R_XTENSA_SLOT7_OP:
	case R_XTENSA_SLOT8_OP:
	case R_XTENSA_SLOT9_OP:
	case R_XTENSA_SLOT10_OP:
	case R_XTENSA_SLOT11_OP:
	case R_XTENSA_SLOT12_OP:
	case R_XTENSA_SLOT13_OP:
	case R_XTENSA_SLOT14_OP:
	case R_XTENSA_SLOT0_ALT:
	case R_XTENSA_SLOT1_ALT:
	case R_XTENSA_SLOT2_ALT:
	case R_XTENSA_SLOT3_ALT:
	case R_XTENSA_SLOT4_ALT:
	case R_XTENSA_SLOT5_ALT:
	case R_XTENSA_SLOT6_ALT:
	case R_XTENSA_SLOT7_ALT:
	case R_XTENSA_SLOT8_ALT:
	case R_XTENSA_SLOT9_ALT:
	case R_XTENSA_SLOT10_ALT:
	case R_XTENSA_SLOT11_ALT:
	case R_XTENSA_SLOT12_ALT:
	case R_XTENSA_SLOT13_ALT:
	case R_XTENSA_SLOT14_ALT:
	case R_XTENSA_ASM_EXPAND:
	case R_XTENSA_ASM_SIMPLIFY:
	case R_XTENSA_DIFF8:
	case R_XTENSA_DIFF16:
	case R_XTENSA_DIFF32:
	  /* Nothing to do for these.  */
	  break;

	case R_XTENSA_GNU_VTINHERIT:
	  /* This relocation describes the C++ object vtable hierarchy.
	     Reconstruct it for later use during GC.  */
	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
	    return FALSE;
	  break;

	case R_XTENSA_GNU_VTENTRY:
	  /* This relocation describes which C++ vtable entries are actually
	     used.  Record for later use during GC.  */
	  if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
	    return FALSE;
	  break;

	default:
	  break;
	}
    }

  return TRUE;
}


static void
elf_xtensa_make_sym_local (struct bfd_link_info *info,
			   struct elf_link_hash_entry *h)
{
  if (info->shared)
    {
      if (h->plt.refcount > 0)
	{
	  /* Will use RELATIVE relocs instead of JMP_SLOT relocs.  */
	  if (h->got.refcount < 0)
	    h->got.refcount = 0;
	  h->got.refcount += h->plt.refcount;
	  h->plt.refcount = 0;
	}
    }
  else
    {
      /* Don't need any dynamic relocations at all.  */
      h->plt.refcount = 0;
      h->got.refcount = 0;
    }
}


static void
elf_xtensa_hide_symbol (struct bfd_link_info *info,
			struct elf_link_hash_entry *h,
			bfd_boolean force_local)
{
  /* For a shared link, move the plt refcount to the got refcount to leave
     space for RELATIVE relocs.  */
  elf_xtensa_make_sym_local (info, h);

  _bfd_elf_link_hash_hide_symbol (info, h, force_local);
}


/* Return the section that should be marked against GC for a given
   relocation.  */

static asection *
elf_xtensa_gc_mark_hook (asection *sec,
			 struct bfd_link_info *info ATTRIBUTE_UNUSED,
			 Elf_Internal_Rela *rel,
			 struct elf_link_hash_entry *h,
			 Elf_Internal_Sym *sym)
{
  if (h)
    {
      switch (ELF32_R_TYPE (rel->r_info))
	{
	case R_XTENSA_GNU_VTINHERIT:
	case R_XTENSA_GNU_VTENTRY:
	  break;

	default:
	  switch (h->root.type)
	    {
	    case bfd_link_hash_defined:
	    case bfd_link_hash_defweak:
	      return h->root.u.def.section;

	    case bfd_link_hash_common:
	      return h->root.u.c.p->section;

	    default:
	      break;
	    }
	}
    }
  else
    return bfd_section_from_elf_index (sec->owner, sym->st_shndx);

  return NULL;
}


/* Update the GOT & PLT entry reference counts
   for the section being removed.  */

static bfd_boolean
elf_xtensa_gc_sweep_hook (bfd *abfd,
			  struct bfd_link_info *info ATTRIBUTE_UNUSED,
			  asection *sec,
			  const Elf_Internal_Rela *relocs)
{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  bfd_signed_vma *local_got_refcounts;
  const Elf_Internal_Rela *rel, *relend;

  if ((sec->flags & SEC_ALLOC) == 0)
    return TRUE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);
  local_got_refcounts = elf_local_got_refcounts (abfd);

  relend = relocs + sec->reloc_count;
  for (rel = relocs; rel < relend; rel++)
    {
      unsigned long r_symndx;
      unsigned int r_type;
      struct elf_link_hash_entry *h = NULL;

      r_symndx = ELF32_R_SYM (rel->r_info);
      if (r_symndx >= symtab_hdr->sh_info)
	h = sym_hashes[r_symndx - symtab_hdr->sh_info];

      r_type = ELF32_R_TYPE (rel->r_info);
      switch (r_type)
	{
	case R_XTENSA_32:
	  if (h == NULL)
	    goto local_literal;
	  if (h->got.refcount > 0)
	    h->got.refcount--;
	  break;

	case R_XTENSA_PLT:
	  if (h == NULL)
	    goto local_literal;
	  if (h->plt.refcount > 0)
	    h->plt.refcount--;
	  break;

	local_literal:
	  if (local_got_refcounts[r_symndx] > 0)
	    local_got_refcounts[r_symndx] -= 1;
	  break;

	default:
	  break;
	}
    }

  return TRUE;
}


/* Create all the dynamic sections.  */

static bfd_boolean
elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
{
  flagword flags, noalloc_flags;
  asection *s;

  /* First do all the standard stuff.  */
  if (! _bfd_elf_create_dynamic_sections (dynobj, info))
    return FALSE;

  /* Create any extra PLT sections in case check_relocs has already
     been called on all the non-dynamic input files.  */
  if (!add_extra_plt_sections (dynobj, plt_reloc_count))
    return FALSE;

  noalloc_flags = (SEC_HAS_CONTENTS | SEC_IN_MEMORY
		   | SEC_LINKER_CREATED | SEC_READONLY);
  flags = noalloc_flags | SEC_ALLOC | SEC_LOAD;

  /* Mark the ".got.plt" section READONLY.  */
  s = bfd_get_section_by_name (dynobj, ".got.plt");
  if (s == NULL
      || ! bfd_set_section_flags (dynobj, s, flags))
    return FALSE;

  /* Create ".rela.got".  */
  s = bfd_make_section (dynobj, ".rela.got");
  if (s == NULL
      || ! bfd_set_section_flags (dynobj, s, flags)
      || ! bfd_set_section_alignment (dynobj, s, 2))
    return FALSE;

  /* Create ".got.loc" (literal tables for use by dynamic linker).  */
  s = bfd_make_section (dynobj, ".got.loc");
  if (s == NULL
      || ! bfd_set_section_flags (dynobj, s, flags)
      || ! bfd_set_section_alignment (dynobj, s, 2))
    return FALSE;

  /* Create ".xt.lit.plt" (literal table for ".got.plt*").  */
  s = bfd_make_section (dynobj, ".xt.lit.plt");
  if (s == NULL
      || ! bfd_set_section_flags (dynobj, s, noalloc_flags)
      || ! bfd_set_section_alignment (dynobj, s, 2))
    return FALSE;

  return TRUE;
}


static bfd_boolean
add_extra_plt_sections (bfd *dynobj, int count)
{
  int chunk;

  /* Iterate over all chunks except 0 which uses the standard ".plt" and
     ".got.plt" sections.  */
  for (chunk = count / PLT_ENTRIES_PER_CHUNK; chunk > 0; chunk--)
    {
      char *sname;
      flagword flags;
      asection *s;

      /* Stop when we find a section has already been created.  */
      if (elf_xtensa_get_plt_section (dynobj, chunk))
	break;

      flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
	       | SEC_LINKER_CREATED | SEC_READONLY);

      sname = (char *) bfd_malloc (10);
      sprintf (sname, ".plt.%u", chunk);
      s = bfd_make_section (dynobj, sname);
      if (s == NULL
	  || ! bfd_set_section_flags (dynobj, s, flags | SEC_CODE)
	  || ! bfd_set_section_alignment (dynobj, s, 2))
	return FALSE;

      sname = (char *) bfd_malloc (14);
      sprintf (sname, ".got.plt.%u", chunk);
      s = bfd_make_section (dynobj, sname);
      if (s == NULL
	  || ! bfd_set_section_flags (dynobj, s, flags)
	  || ! bfd_set_section_alignment (dynobj, s, 2))
	return FALSE;
    }

  return TRUE;
}


/* Adjust a symbol defined by a dynamic object and referenced by a
   regular object.  The current definition is in some section of the
   dynamic object, but we're not including those sections.  We have to
   change the definition to something the rest of the link can
   understand.  */

static bfd_boolean
elf_xtensa_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
				  struct elf_link_hash_entry *h)
{
  /* If this is a weak symbol, and there is a real definition, the
     processor independent code will have arranged for us to see the
     real definition first, and we can just use the same value.  */
  if (h->u.weakdef)
    {
      BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
      h->root.u.def.section = h->u.weakdef->root.u.def.section;
      h->root.u.def.value = h->u.weakdef->root.u.def.value;
      return TRUE;
    }

  /* This is a reference to a symbol defined by a dynamic object.  The
     reference must go through the GOT, so there's no need for COPY relocs,
     .dynbss, etc.  */

  return TRUE;
}


static bfd_boolean
elf_xtensa_fix_refcounts (struct elf_link_hash_entry *h, void *arg)
{
  struct bfd_link_info *info = (struct bfd_link_info *) arg;

  if (h->root.type == bfd_link_hash_warning)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;

  if (! xtensa_elf_dynamic_symbol_p (h, info))
    elf_xtensa_make_sym_local (info, h);

  return TRUE;
}


static bfd_boolean
elf_xtensa_allocate_plt_size (struct elf_link_hash_entry *h, void *arg)
{
  asection *srelplt = (asection *) arg;

  if (h->root.type == bfd_link_hash_warning)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;

  if (h->plt.refcount > 0)
    srelplt->size += (h->plt.refcount * sizeof (Elf32_External_Rela));

  return TRUE;
}


static bfd_boolean
elf_xtensa_allocate_got_size (struct elf_link_hash_entry *h, void *arg)
{
  asection *srelgot = (asection *) arg;

  if (h->root.type == bfd_link_hash_warning)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;

  if (h->got.refcount > 0)
    srelgot->size += (h->got.refcount * sizeof (Elf32_External_Rela));

  return TRUE;
}


static void
elf_xtensa_allocate_local_got_size (struct bfd_link_info *info,
				    asection *srelgot)
{
  bfd *i;

  for (i = info->input_bfds; i; i = i->link_next)
    {
      bfd_signed_vma *local_got_refcounts;
      bfd_size_type j, cnt;
      Elf_Internal_Shdr *symtab_hdr;

      local_got_refcounts = elf_local_got_refcounts (i);
      if (!local_got_refcounts)
	continue;

      symtab_hdr = &elf_tdata (i)->symtab_hdr;
      cnt = symtab_hdr->sh_info;

      for (j = 0; j < cnt; ++j)
	{
	  if (local_got_refcounts[j] > 0)
	    srelgot->size += (local_got_refcounts[j]
			      * sizeof (Elf32_External_Rela));
	}
    }
}


/* Set the sizes of the dynamic sections.  */

static bfd_boolean
elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
				  struct bfd_link_info *info)
{
  bfd *dynobj, *abfd;
  asection *s, *srelplt, *splt, *sgotplt, *srelgot, *spltlittbl, *sgotloc;
  bfd_boolean relplt, relgot;
  int plt_entries, plt_chunks, chunk;

  plt_entries = 0;
  plt_chunks = 0;
  srelgot = 0;

  dynobj = elf_hash_table (info)->dynobj;
  if (dynobj == NULL)
    abort ();

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Set the contents of the .interp section to the interpreter.  */
      if (info->executable)
	{
	  s = bfd_get_section_by_name (dynobj, ".interp");
	  if (s == NULL)
	    abort ();
	  s->size = sizeof ELF_DYNAMIC_INTERPRETER;
	  s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
	}

      /* Allocate room for one word in ".got".  */
      s = bfd_get_section_by_name (dynobj, ".got");
      if (s == NULL)
	abort ();
      s->size = 4;

      /* Adjust refcounts for symbols that we now know are not "dynamic".  */
      elf_link_hash_traverse (elf_hash_table (info),
			      elf_xtensa_fix_refcounts,
			      (void *) info);

      /* Allocate space in ".rela.got" for literals that reference
	 global symbols.  */
      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
      if (srelgot == NULL)
	abort ();
      elf_link_hash_traverse (elf_hash_table (info),
			      elf_xtensa_allocate_got_size,
			      (void *) srelgot);

      /* If we are generating a shared object, we also need space in
	 ".rela.got" for R_XTENSA_RELATIVE relocs for literals that
	 reference local symbols.  */
      if (info->shared)
	elf_xtensa_allocate_local_got_size (info, srelgot);

      /* Allocate space in ".rela.plt" for literals that have PLT entries.  */
      srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
      if (srelplt == NULL)
	abort ();
      elf_link_hash_traverse (elf_hash_table (info),
			      elf_xtensa_allocate_plt_size,
			      (void *) srelplt);

      /* Allocate space in ".plt" to match the size of ".rela.plt".  For
	 each PLT entry, we need the PLT code plus a 4-byte literal.
	 For each chunk of ".plt", we also need two more 4-byte
	 literals, two corresponding entries in ".rela.got", and an
	 8-byte entry in ".xt.lit.plt".  */
      spltlittbl = bfd_get_section_by_name (dynobj, ".xt.lit.plt");
      if (spltlittbl == NULL)
	abort ();

      plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
      plt_chunks =
	(plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;

      /* Iterate over all the PLT chunks, including any extra sections
	 created earlier because the initial count of PLT relocations
	 was an overestimate.  */
      for (chunk = 0;
	   (splt = elf_xtensa_get_plt_section (dynobj, chunk)) != NULL;
	   chunk++)
	{
	  int chunk_entries;

	  sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk);
	  if (sgotplt == NULL)
	    abort ();

	  if (chunk < plt_chunks - 1)
	    chunk_entries = PLT_ENTRIES_PER_CHUNK;
	  else if (chunk == plt_chunks - 1)
	    chunk_entries = plt_entries - (chunk * PLT_ENTRIES_PER_CHUNK);
	  else
	    chunk_entries = 0;

	  if (chunk_entries != 0)
	    {
	      sgotplt->size = 4 * (chunk_entries + 2);
	      splt->size = PLT_ENTRY_SIZE * chunk_entries;
	      srelgot->size += 2 * sizeof (Elf32_External_Rela);
	      spltlittbl->size += 8;
	    }
	  else
	    {
	      sgotplt->size = 0;
	      splt->size = 0;
	    }
	}

      /* Allocate space in ".got.loc" to match the total size of all the
	 literal tables.  */
      sgotloc = bfd_get_section_by_name (dynobj, ".got.loc");
      if (sgotloc == NULL)
	abort ();
      sgotloc->size = spltlittbl->size;
      for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next)
	{
	  if (abfd->flags & DYNAMIC)
	    continue;
	  for (s = abfd->sections; s != NULL; s = s->next)
	    {
	      if (! elf_discarded_section (s)
		  && xtensa_is_littable_section (s)
		  && s != spltlittbl)
		sgotloc->size += s->size;
	    }
	}
    }

  /* Allocate memory for dynamic sections.  */
  relplt = FALSE;
  relgot = FALSE;
  for (s = dynobj->sections; s != NULL; s = s->next)
    {
      const char *name;
      bfd_boolean strip;

      if ((s->flags & SEC_LINKER_CREATED) == 0)
	continue;

      /* It's OK to base decisions on the section name, because none
	 of the dynobj section names depend upon the input files.  */
      name = bfd_get_section_name (dynobj, s);

      strip = FALSE;

      if (strncmp (name, ".rela", 5) == 0)
	{
	  if (strcmp (name, ".rela.plt") == 0)
	    relplt = TRUE;
	  else if (strcmp (name, ".rela.got") == 0)
	    relgot = TRUE;

	  /* We use the reloc_count field as a counter if we need
	     to copy relocs into the output file.  */
	  s->reloc_count = 0;
	}
      else if (strncmp (name, ".plt.", 5) == 0
	       || strncmp (name, ".got.plt.", 9) == 0)
	{
	  if (s->size == 0)
	    {
	      /* If we don't need this section, strip it from the output
		 file.  We must create the ".plt*" and ".got.plt*"
		 sections in create_dynamic_sections and/or check_relocs
		 based on a conservative estimate of the PLT relocation
		 count, because the sections must be created before the
		 linker maps input sections to output sections.  The
		 linker does that before size_dynamic_sections, where we
		 compute the exact size of the PLT, so there may be more
		 of these sections than are actually needed.  */
	      strip = TRUE;
	    }
	}
      else if (strcmp (name, ".got") != 0
	       && strcmp (name, ".plt") != 0
	       && strcmp (name, ".got.plt") != 0
	       && strcmp (name, ".xt.lit.plt") != 0
	       && strcmp (name, ".got.loc") != 0)
	{
	  /* It's not one of our sections, so don't allocate space.  */
	  continue;
	}

      if (strip)
	_bfd_strip_section_from_output (info, s);
      else
	{
	  /* Allocate memory for the section contents.  */
	  s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
	  if (s->contents == NULL && s->size != 0)
	    return FALSE;
	}
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      /* Add the special XTENSA_RTLD relocations now.  The offsets won't be
	 known until finish_dynamic_sections, but we need to get the relocs
	 in place before they are sorted.  */
      if (srelgot == NULL)
	abort ();
      for (chunk = 0; chunk < plt_chunks; chunk++)
	{
	  Elf_Internal_Rela irela;
	  bfd_byte *loc;

	  irela.r_offset = 0;
	  irela.r_info = ELF32_R_INFO (0, R_XTENSA_RTLD);
	  irela.r_addend = 0;

	  loc = (srelgot->contents
		 + srelgot->reloc_count * sizeof (Elf32_External_Rela));
	  bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
	  bfd_elf32_swap_reloca_out (output_bfd, &irela,
				     loc + sizeof (Elf32_External_Rela));
	  srelgot->reloc_count += 2;
	}

      /* Add some entries to the .dynamic section.  We fill in the
	 values later, in elf_xtensa_finish_dynamic_sections, but we
	 must add the entries now so that we get the correct size for
	 the .dynamic section.  The DT_DEBUG entry is filled in by the
	 dynamic linker and used by the debugger.  */
#define add_dynamic_entry(TAG, VAL) \
  _bfd_elf_add_dynamic_entry (info, TAG, VAL)

      if (! info->shared)
	{
	  if (!add_dynamic_entry (DT_DEBUG, 0))
	    return FALSE;
	}

      if (relplt)
	{
	  if (!add_dynamic_entry (DT_PLTGOT, 0)
	      || !add_dynamic_entry (DT_PLTRELSZ, 0)
	      || !add_dynamic_entry (DT_PLTREL, DT_RELA)
	      || !add_dynamic_entry (DT_JMPREL, 0))
	    return FALSE;
	}

      if (relgot)
	{
	  if (!add_dynamic_entry (DT_RELA, 0)
	      || !add_dynamic_entry (DT_RELASZ, 0)
	      || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
	    return FALSE;
	}

      if (!add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0)
	  || !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0))
	return FALSE;
    }
#undef add_dynamic_entry

  return TRUE;
}


/* Remove any PT_LOAD segments with no allocated sections.  Prior to
   binutils 2.13, this function used to remove the non-SEC_ALLOC
   sections from PT_LOAD segments, but that task has now been moved
   into elf.c.  We still need this function to remove any empty
   segments that result, but there's nothing Xtensa-specific about
   this and it probably ought to be moved into elf.c as well.  */

static bfd_boolean
elf_xtensa_modify_segment_map (bfd *abfd,
			       struct bfd_link_info *info ATTRIBUTE_UNUSED)
{
  struct elf_segment_map **m_p;

  m_p = &elf_tdata (abfd)->segment_map;
  while (*m_p)
    {
      if ((*m_p)->p_type == PT_LOAD && (*m_p)->count == 0)
	*m_p = (*m_p)->next;
      else
	m_p = &(*m_p)->next;
    }
  return TRUE;
}


/* Perform the specified relocation.  The instruction at (contents + address)
   is modified to set one operand to represent the value in "relocation".  The
   operand position is determined by the relocation type recorded in the
   howto.  */

#define CALL_SEGMENT_BITS (30)
#define CALL_SEGMENT_SIZE (1 << CALL_SEGMENT_BITS)

static bfd_reloc_status_type
elf_xtensa_do_reloc (reloc_howto_type *howto,
		     bfd *abfd,
		     asection *input_section,
		     bfd_vma relocation,
		     bfd_byte *contents,
		     bfd_vma address,
		     bfd_boolean is_weak_undef,
		     char **error_message)
{
  xtensa_format fmt;
  xtensa_opcode opcode;
  xtensa_isa isa = xtensa_default_isa;
  static xtensa_insnbuf ibuff = NULL;
  static xtensa_insnbuf sbuff = NULL;
  bfd_vma self_address = 0;
  bfd_size_type input_size;
  int opnd, slot;
  uint32 newval;

  if (!ibuff)
    {
      ibuff = xtensa_insnbuf_alloc (isa);
      sbuff = xtensa_insnbuf_alloc (isa);
    }

  input_size = bfd_get_section_limit (abfd, input_section);

  switch (howto->type)
    {
    case R_XTENSA_NONE:
    case R_XTENSA_DIFF8:
    case R_XTENSA_DIFF16:
    case R_XTENSA_DIFF32:
      return bfd_reloc_ok;

    case R_XTENSA_ASM_EXPAND:
      if (!is_weak_undef)
	{
	  /* Check for windowed CALL across a 1GB boundary.  */
	  xtensa_opcode opcode =
	    get_expanded_call_opcode (contents + address,
				      input_size - address, 0);
	  if (is_windowed_call_opcode (opcode))
	    {
	      self_address = (input_section->output_section->vma
			      + input_section->output_offset
			      + address);
	      if ((self_address >> CALL_SEGMENT_BITS)
		  != (relocation >> CALL_SEGMENT_BITS)) 
		{
		  *error_message = "windowed longcall crosses 1GB boundary; "
		    "return may fail";
		  return bfd_reloc_dangerous;
		}
	    }
	}
      return bfd_reloc_ok;

    case R_XTENSA_ASM_SIMPLIFY:
      {
        /* Convert the L32R/CALLX to CALL.  */
	bfd_reloc_status_type retval =
	  elf_xtensa_do_asm_simplify (contents, address, input_size,
				      error_message);
	if (retval != bfd_reloc_ok)
	  return bfd_reloc_dangerous;

	/* The CALL needs to be relocated.  Continue below for that part.  */
	address += 3;
	howto = &elf_howto_table[(unsigned) R_XTENSA_SLOT0_OP ];
      }
      break;

    case R_XTENSA_32:
    case R_XTENSA_PLT:
      {
	bfd_vma x;
	x = bfd_get_32 (abfd, contents + address);
	x = x + relocation;
	bfd_put_32 (abfd, x, contents + address);
      }
      return bfd_reloc_ok;
    }

  /* Only instruction slot-specific relocations handled below.... */
  slot = get_relocation_slot (howto->type);
  if (slot == XTENSA_UNDEFINED)
    {
      *error_message = "unexpected relocation";
      return bfd_reloc_dangerous;
    }

  /* Read the instruction into a buffer and decode the opcode.  */
  xtensa_insnbuf_from_chars (isa, ibuff, contents + address,
			     input_size - address);
  fmt = xtensa_format_decode (isa, ibuff);
  if (fmt == XTENSA_UNDEFINED)
    {
      *error_message = "cannot decode instruction format";
      return bfd_reloc_dangerous;
    }

  xtensa_format_get_slot (isa, fmt, slot, ibuff, sbuff);

  opcode = xtensa_opcode_decode (isa, fmt, slot, sbuff);
  if (opcode == XTENSA_UNDEFINED)
    {
      *error_message = "cannot decode instruction opcode";
      return bfd_reloc_dangerous;
    }

  /* Check for opcode-specific "alternate" relocations.  */
  if (is_alt_relocation (howto->type))
    {
      if (opcode == get_l32r_opcode ())
	{
	  /* Handle the special-case of non-PC-relative L32R instructions.  */
	  bfd *output_bfd = input_section->output_section->owner;
	  asection *lit4_sec = bfd_get_section_by_name (output_bfd, ".lit4");
	  if (!lit4_sec)
	    {
	      *error_message = "relocation references missing .lit4 section";
	      return bfd_reloc_dangerous;
	    }
	  self_address = ((lit4_sec->vma & ~0xfff)
			  + 0x40000 - 3); /* -3 to compensate for do_reloc */
	  newval = relocation;
	  opnd = 1;
	}
      else if (opcode == get_const16_opcode ())
	{
	  /* ALT used for high 16 bits.  */
	  newval = relocation >> 16;
	  opnd = 1;
	}
      else
	{
	  /* No other "alternate" relocations currently defined.  */
	  *error_message = "unexpected relocation";
	  return bfd_reloc_dangerous;
	}
    }
  else /* Not an "alternate" relocation.... */
    {
      if (opcode == get_const16_opcode ())
	{
	  newval = relocation & 0xffff;
	  opnd = 1;
	}
      else
	{
	  /* ...normal PC-relative relocation.... */

	  /* Determine which operand is being relocated.  */
	  opnd = get_relocation_opnd (opcode, howto->type);
	  if (opnd == XTENSA_UNDEFINED)
	    {
	      *error_message = "unexpected relocation";
	      return bfd_reloc_dangerous;
	    }

	  if (!howto->pc_relative)
	    {
	      *error_message = "expected PC-relative relocation";
	      return bfd_reloc_dangerous;
	    }

	  /* Calculate the PC address for this instruction.  */
	  self_address = (input_section->output_section->vma
			  + input_section->output_offset
			  + address);

	  newval = relocation;
	}
    }

  /* Apply the relocation.  */
  if (xtensa_operand_do_reloc (isa, opcode, opnd, &newval, self_address)
      || xtensa_operand_encode (isa, opcode, opnd, &newval)
      || xtensa_operand_set_field (isa, opcode, opnd, fmt, slot,
				   sbuff, newval))
    {
      *error_message = build_encoding_error_message (opcode, relocation);
      return bfd_reloc_dangerous;
    }

  /* Check for calls across 1GB boundaries.  */
  if (is_direct_call_opcode (opcode)
      && is_windowed_call_opcode (opcode))
    {
      if ((self_address >> CALL_SEGMENT_BITS)
	  != (relocation >> CALL_SEGMENT_BITS)) 
	{
	  *error_message =
	    "windowed call crosses 1GB boundary; return may fail";
	  return bfd_reloc_dangerous;
	}
    }

  /* Write the modified instruction back out of the buffer.  */
  xtensa_format_set_slot (isa, fmt, slot, ibuff, sbuff);
  xtensa_insnbuf_to_chars (isa, ibuff, contents + address,
			   input_size - address);
  return bfd_reloc_ok;
}


static char *
vsprint_msg (const char *origmsg, const char *fmt, int arglen, ...)
{
  /* To reduce the size of the memory leak,
     we only use a single message buffer.  */
  static bfd_size_type alloc_size = 0;
  static char *message = NULL;
  bfd_size_type orig_len, len = 0;
  bfd_boolean is_append;

  VA_OPEN (ap, arglen);
  VA_FIXEDARG (ap, const char *, origmsg);
  
  is_append = (origmsg == message);  

  orig_len = strlen (origmsg);
  len = orig_len + strlen (fmt) + arglen + 20;
  if (len > alloc_size)
    {
      message = (char *) bfd_realloc (message, len);
      alloc_size = len;
    }
  if (!is_append)
    memcpy (message, origmsg, orig_len);
  vsprintf (message + orig_len, fmt, ap);
  VA_CLOSE (ap);
  return message;
}


static char *
build_encoding_error_message (xtensa_opcode opcode, bfd_vma target_address)
{
  const char *opname = xtensa_opcode_name (xtensa_default_isa, opcode);
  const char *msg;

  msg = "cannot encode";
  if (is_direct_call_opcode (opcode))
    {
      if ((target_address & 0x3) != 0)
	msg = "misaligned call target";
      else
	msg = "call target out of range";
    }
  else if (opcode == get_l32r_opcode ())
    {
      if ((target_address & 0x3) != 0)
	msg = "misaligned literal target";
      else
	msg = "literal target out of range";
    }

  return vsprint_msg (opname, ": %s", strlen (msg) + 2, msg);
}


/* This function is registered as the "special_function" in the
   Xtensa howto for handling simplify operations.
   bfd_perform_relocation / bfd_install_relocation use it to
   perform (install) the specified relocation.  Since this replaces the code
   in bfd_perform_relocation, it is basically an Xtensa-specific,
   stripped-down version of bfd_perform_relocation.  */

static bfd_reloc_status_type
bfd_elf_xtensa_reloc (bfd *abfd,
		      arelent *reloc_entry,
		      asymbol *symbol,
		      void *data,
		      asection *input_section,
		      bfd *output_bfd,
		      char **error_message)
{
  bfd_vma relocation;
  bfd_reloc_status_type flag;
  bfd_size_type octets = reloc_entry->address * bfd_octets_per_byte (abfd);
  bfd_vma output_base = 0;
  reloc_howto_type *howto = reloc_entry->howto;
  asection *reloc_target_output_section;
  bfd_boolean is_weak_undef;

  /* ELF relocs are against symbols.  If we are producing relocatable
     output, and the reloc is against an external symbol, the resulting
     reloc will also be against the same symbol.  In such a case, we
     don't want to change anything about the way the reloc is handled,
     since it will all be done at final link time.  This test is similar
     to what bfd_elf_generic_reloc does except that it lets relocs with
     howto->partial_inplace go through even if the addend is non-zero.
     (The real problem is that partial_inplace is set for XTENSA_32
     relocs to begin with, but that's a long story and there's little we
     can do about it now....)  */

  if (output_bfd && (symbol->flags & BSF_SECTION_SYM) == 0)
    {
      reloc_entry->address += input_section->output_offset;
      return bfd_reloc_ok;
    }

  /* Is the address of the relocation really within the section?  */
  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
    return bfd_reloc_outofrange;

  /* Work out which section the relocation is targeted at and the
     initial relocation command value.  */

  /* Get symbol value.  (Common symbols are special.)  */
  if (bfd_is_com_section (symbol->section))
    relocation = 0;
  else
    relocation = symbol->value;

  reloc_target_output_section = symbol->section->output_section;

  /* Convert input-section-relative symbol value to absolute.  */
  if ((output_bfd && !howto->partial_inplace)
      || reloc_target_output_section == NULL)
    output_base = 0;
  else
    output_base = reloc_target_output_section->vma;

  relocation += output_base + symbol->section->output_offset;

  /* Add in supplied addend.  */
  relocation += reloc_entry->addend;

  /* Here the variable relocation holds the final address of the
     symbol we are relocating against, plus any addend.  */
  if (output_bfd)
    {
      if (!howto->partial_inplace)
	{
	  /* This is a partial relocation, and we want to apply the relocation
	     to the reloc entry rather than the raw data.  Everything except
	     relocations against section symbols has already been handled
	     above.  */

	  BFD_ASSERT (symbol->flags & BSF_SECTION_SYM);
	  reloc_entry->addend = relocation;
	  reloc_entry->address += input_section->output_offset;
	  return bfd_reloc_ok;
	}
      else
	{
	  reloc_entry->address += input_section->output_offset;
	  reloc_entry->addend = 0;
	}
    }

  is_weak_undef = (bfd_is_und_section (symbol->section)
		   && (symbol->flags & BSF_WEAK) != 0);
  flag = elf_xtensa_do_reloc (howto, abfd, input_section, relocation,
			      (bfd_byte *) data, (bfd_vma) octets,
			      is_weak_undef, error_message);

  if (flag == bfd_reloc_dangerous)
    {
      /* Add the symbol name to the error message.  */
      if (! *error_message)
	*error_message = "";
      *error_message = vsprint_msg (*error_message, ": (%s + 0x%lx)",
				    strlen (symbol->name) + 17,
				    symbol->name, reloc_entry->addend);
    }

  return flag;
}


/* Set up an entry in the procedure linkage table.  */

static bfd_vma
elf_xtensa_create_plt_entry (bfd *dynobj,
			     bfd *output_bfd,
			     unsigned reloc_index)
{
  asection *splt, *sgotplt;
  bfd_vma plt_base, got_base;
  bfd_vma code_offset, lit_offset;
  int chunk;

  chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
  splt = elf_xtensa_get_plt_section (dynobj, chunk);
  sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk);
  BFD_ASSERT (splt != NULL && sgotplt != NULL);

  plt_base = splt->output_section->vma + splt->output_offset;
  got_base = sgotplt->output_section->vma + sgotplt->output_offset;

  lit_offset = 8 + (reloc_index % PLT_ENTRIES_PER_CHUNK) * 4;
  code_offset = (reloc_index % PLT_ENTRIES_PER_CHUNK) * PLT_ENTRY_SIZE;

  /* Fill in the literal entry.  This is the offset of the dynamic
     relocation entry.  */
  bfd_put_32 (output_bfd, reloc_index * sizeof (Elf32_External_Rela),
	      sgotplt->contents + lit_offset);

  /* Fill in the entry in the procedure linkage table.  */
  memcpy (splt->contents + code_offset,
	  (bfd_big_endian (output_bfd)
	   ? elf_xtensa_be_plt_entry
	   : elf_xtensa_le_plt_entry),
	  PLT_ENTRY_SIZE);
  bfd_put_16 (output_bfd, l32r_offset (got_base + 0,
				       plt_base + code_offset + 3),
	      splt->contents + code_offset + 4);
  bfd_put_16 (output_bfd, l32r_offset (got_base + 4,
				       plt_base + code_offset + 6),
	      splt->contents + code_offset + 7);
  bfd_put_16 (output_bfd, l32r_offset (got_base + lit_offset,
				       plt_base + code_offset + 9),
	      splt->contents + code_offset + 10);

  return plt_base + code_offset;
}


/* Relocate an Xtensa ELF section.  This is invoked by the linker for
   both relocatable and final links.  */

static bfd_boolean
elf_xtensa_relocate_section (bfd *output_bfd,
			     struct bfd_link_info *info,
			     bfd *input_bfd,
			     asection *input_section,
			     bfd_byte *contents,
			     Elf_Internal_Rela *relocs,
			     Elf_Internal_Sym *local_syms,
			     asection **local_sections)
{
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;
  struct elf_link_hash_entry **sym_hashes;
  asection *srelgot, *srelplt;
  bfd *dynobj;
  property_table_entry *lit_table = 0;
  int ltblsize = 0;
  char *error_message = NULL;
  bfd_size_type input_size;

  if (!xtensa_default_isa)
    xtensa_default_isa = xtensa_isa_init (0, 0);

  dynobj = elf_hash_table (info)->dynobj;
  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);

  srelgot = NULL;
  srelplt = NULL;
  if (dynobj)
    {
      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");;
      srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
    }

  if (elf_hash_table (info)->dynamic_sections_created)
    {
      ltblsize = xtensa_read_table_entries (input_bfd, input_section,
					    &lit_table, XTENSA_LIT_SEC_NAME,
					    TRUE);
      if (ltblsize < 0)
	return FALSE;
    }

  input_size = bfd_get_section_limit (input_bfd, input_section);

  rel = relocs;
  relend = relocs + input_section->reloc_count;
  for (; rel < relend; rel++)
    {
      int r_type;
      reloc_howto_type *howto;
      unsigned long r_symndx;
      struct elf_link_hash_entry *h;
      Elf_Internal_Sym *sym;
      asection *sec;
      bfd_vma relocation;
      bfd_reloc_status_type r;
      bfd_boolean is_weak_undef;
      bfd_boolean unresolved_reloc;
      bfd_boolean warned;

      r_type = ELF32_R_TYPE (rel->r_info);
      if (r_type == (int) R_XTENSA_GNU_VTINHERIT
	  || r_type == (int) R_XTENSA_GNU_VTENTRY)
	continue;

      if (r_type < 0 || r_type >= (int) R_XTENSA_max)
	{
	  bfd_set_error (bfd_error_bad_value);
	  return FALSE;
	}
      howto = &elf_howto_table[r_type];

      r_symndx = ELF32_R_SYM (rel->r_info);

      if (info->relocatable)
	{
	  /* This is a relocatable link.
	     1) If the reloc is against a section symbol, adjust
	     according to the output section.
	     2) If there is a new target for this relocation,
	     the new target will be in the same output section.
	     We adjust the relocation by the output section
	     difference.  */

	  if (relaxing_section)
	    {
	      /* Check if this references a section in another input file.  */
	      if (!do_fix_for_relocatable_link (rel, input_bfd, input_section,
						contents))
		return FALSE;
	      r_type = ELF32_R_TYPE (rel->r_info);
	    }

	  if (r_type == R_XTENSA_ASM_SIMPLIFY)
	    {
	      char *error_message = NULL;
	      /* Convert ASM_SIMPLIFY into the simpler relocation
		 so that they never escape a relaxing link.  */
	      r = contract_asm_expansion (contents, input_size, rel,
					  &error_message);
	      if (r != bfd_reloc_ok)
		{
		  if (!((*info->callbacks->reloc_dangerous)
			(info, error_message, input_bfd, input_section,
			 rel->r_offset)))
		    return FALSE;
		}
	      r_type = ELF32_R_TYPE (rel->r_info);
	    }

	  /* This is a relocatable link, so we don't have to change
	     anything unless the reloc is against a section symbol,
	     in which case we have to adjust according to where the
	     section symbol winds up in the output section.  */
	  if (r_symndx < symtab_hdr->sh_info)
	    {
	      sym = local_syms + r_symndx;
	      if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
		{
		  sec = local_sections[r_symndx];
		  rel->r_addend += sec->output_offset + sym->st_value;
		}
	    }

	  /* If there is an addend with a partial_inplace howto,
	     then move the addend to the contents.  This is a hack
	     to work around problems with DWARF in relocatable links
	     with some previous version of BFD.  Now we can't easily get
	     rid of the hack without breaking backward compatibility.... */
	  if (rel->r_addend)
	    {
	      howto = &elf_howto_table[r_type];
	      if (howto->partial_inplace)
		{
		  r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
					   rel->r_addend, contents,
					   rel->r_offset, FALSE,
					   &error_message);
		  if (r != bfd_reloc_ok)
		    {
		      if (!((*info->callbacks->reloc_dangerous)
			    (info, error_message, input_bfd, input_section,
			     rel->r_offset)))
			return FALSE;
		    }
		  rel->r_addend = 0;
		}
	    }

	  /* Done with work for relocatable link; continue with next reloc.  */
	  continue;
	}

      /* This is a final link.  */

      h = NULL;
      sym = NULL;
      sec = NULL;
      is_weak_undef = FALSE;
      unresolved_reloc = FALSE;
      warned = FALSE;

      if (howto->partial_inplace)
	{
	  /* Because R_XTENSA_32 was made partial_inplace to fix some
	     problems with DWARF info in partial links, there may be
	     an addend stored in the contents.  Take it out of there
	     and move it back into the addend field of the reloc.  */
	  rel->r_addend += bfd_get_32 (input_bfd, contents + rel->r_offset);
	  bfd_put_32 (input_bfd, 0, contents + rel->r_offset);
	}

      if (r_symndx < symtab_hdr->sh_info)
	{
	  sym = local_syms + r_symndx;
	  sec = local_sections[r_symndx];
	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
	}
      else
	{
	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
				   r_symndx, symtab_hdr, sym_hashes,
				   h, sec, relocation,
				   unresolved_reloc, warned);

	  if (relocation == 0
	      && !unresolved_reloc
	      && h->root.type == bfd_link_hash_undefweak)
	    is_weak_undef = TRUE;
	}

      if (relaxing_section)
	{
	  /* Check if this references a section in another input file.  */
	  do_fix_for_final_link (rel, input_bfd, input_section, contents,
				 &relocation);

	  /* Update some already cached values.  */
	  r_type = ELF32_R_TYPE (rel->r_info);
	  howto = &elf_howto_table[r_type];
	}

      /* Sanity check the address.  */
      if (rel->r_offset >= input_size
	  && ELF32_R_TYPE (rel->r_info) != R_XTENSA_NONE)
	{
	  (*_bfd_error_handler)
	    (_("%B(%A+0x%lx): relocation offset out of range (size=0x%x)"),
	     input_bfd, input_section, rel->r_offset, input_size);
	  bfd_set_error (bfd_error_bad_value);
	  return FALSE;
	}

      /* Generate dynamic relocations.  */
      if (elf_hash_table (info)->dynamic_sections_created)
	{
	  bfd_boolean dynamic_symbol = xtensa_elf_dynamic_symbol_p (h, info);

	  if (dynamic_symbol && is_operand_relocation (r_type))
	    {
	      /* This is an error.  The symbol's real value won't be known
		 until runtime and it's likely to be out of range anyway.  */
	      const char *name = h->root.root.string;
	      error_message = vsprint_msg ("invalid relocation for dynamic "
					   "symbol", ": %s",
					   strlen (name) + 2, name);
	      if (!((*info->callbacks->reloc_dangerous)
		    (info, error_message, input_bfd, input_section,
		     rel->r_offset)))
		return FALSE;
	    }
	  else if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_PLT)
		   && (input_section->flags & SEC_ALLOC) != 0
		   && (dynamic_symbol || info->shared))
	    {
	      Elf_Internal_Rela outrel;
	      bfd_byte *loc;
	      asection *srel;

	      if (dynamic_symbol && r_type == R_XTENSA_PLT)
		srel = srelplt;
	      else
		srel = srelgot;

	      BFD_ASSERT (srel != NULL);

	      outrel.r_offset =
		_bfd_elf_section_offset (output_bfd, info,
					 input_section, rel->r_offset);

	      if ((outrel.r_offset | 1) == (bfd_vma) -1)
		memset (&outrel, 0, sizeof outrel);
	      else
		{
		  outrel.r_offset += (input_section->output_section->vma
				      + input_section->output_offset);

		  /* Complain if the relocation is in a read-only section
		     and not in a literal pool.  */
		  if ((input_section->flags & SEC_READONLY) != 0
		      && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
						      outrel.r_offset))
		    {
		      error_message =
			_("dynamic relocation in read-only section");
		      if (!((*info->callbacks->reloc_dangerous)
			    (info, error_message, input_bfd, input_section,
			     rel->r_offset)))
			return FALSE;
		    }

		  if (dynamic_symbol)
		    {
		      outrel.r_addend = rel->r_addend;
		      rel->r_addend = 0;

		      if (r_type == R_XTENSA_32)
			{
			  outrel.r_info =
			    ELF32_R_INFO (h->dynindx, R_XTENSA_GLOB_DAT);
			  relocation = 0;
			}
		      else /* r_type == R_XTENSA_PLT */
			{
			  outrel.r_info =
			    ELF32_R_INFO (h->dynindx, R_XTENSA_JMP_SLOT);

			  /* Create the PLT entry and set the initial
			     contents of the literal entry to the address of
			     the PLT entry.  */
			  relocation =
			    elf_xtensa_create_plt_entry (dynobj, output_bfd,
							 srel->reloc_count);
			}
		      unresolved_reloc = FALSE;
		    }
		  else
		    {
		      /* Generate a RELATIVE relocation.  */
		      outrel.r_info = ELF32_R_INFO (0, R_XTENSA_RELATIVE);
		      outrel.r_addend = 0;
		    }
		}

	      loc = (srel->contents
		     + srel->reloc_count++ * sizeof (Elf32_External_Rela));
	      bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
	      BFD_ASSERT (sizeof (Elf32_External_Rela) * srel->reloc_count
			  <= srel->size);
	    }
	}

      /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
	 because such sections are not SEC_ALLOC and thus ld.so will
	 not process them.  */
      if (unresolved_reloc
	  && !((input_section->flags & SEC_DEBUGGING) != 0
	       && h->def_dynamic))
	(*_bfd_error_handler)
	  (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
	   input_bfd,
	   input_section,
	   (long) rel->r_offset,
	   h->root.root.string);

      /* There's no point in calling bfd_perform_relocation here.
	 Just go directly to our "special function".  */
      r = elf_xtensa_do_reloc (howto, input_bfd, input_section,
			       relocation + rel->r_addend,
			       contents, rel->r_offset, is_weak_undef,
			       &error_message);

      if (r != bfd_reloc_ok && !warned)
	{
	  const char *name;

	  BFD_ASSERT (r == bfd_reloc_dangerous || r == bfd_reloc_other);
	  BFD_ASSERT (error_message != NULL);

	  if (h)
	    name = h->root.root.string;
	  else
	    {
	      name = bfd_elf_string_from_elf_section
		(input_bfd, symtab_hdr->sh_link, sym->st_name);
	      if (name && *name == '\0')
		name = bfd_section_name (input_bfd, sec);
	    }
	  if (name)
	    {
	      if (rel->r_addend == 0)
		error_message = vsprint_msg (error_message, ": %s",
					     strlen (name) + 2, name);
	      else
		error_message = vsprint_msg (error_message, ": (%s+0x%x)",
					     strlen (name) + 22,
					     name, rel->r_addend);
	    }

	  if (!((*info->callbacks->reloc_dangerous)
		(info, error_message, input_bfd, input_section,
		 rel->r_offset)))
	    return FALSE;
	}
    }

  if (lit_table)
    free (lit_table);

  input_section->reloc_done = TRUE;

  return TRUE;
}


/* Finish up dynamic symbol handling.  There's not much to do here since
   the PLT and GOT entries are all set up by relocate_section.  */

static bfd_boolean
elf_xtensa_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
				  struct bfd_link_info *info ATTRIBUTE_UNUSED,
				  struct elf_link_hash_entry *h,
				  Elf_Internal_Sym *sym)
{
  if (h->needs_plt
      && !h->def_regular)
    {
      /* Mark the symbol as undefined, rather than as defined in
	 the .plt section.  Leave the value alone.  */
      sym->st_shndx = SHN_UNDEF;
    }

  /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
  if (strcmp (h->root.root.string, "_DYNAMIC") == 0
      || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
    sym->st_shndx = SHN_ABS;

  return TRUE;
}


/* Combine adjacent literal table entries in the output.  Adjacent
   entries within each input section may have been removed during
   relaxation, but we repeat the process here, even though it's too late
   to shrink the output section, because it's important to minimize the
   number of literal table entries to reduce the start-up work for the
   runtime linker.  Returns the number of remaining table entries or -1
   on error.  */

static int
elf_xtensa_combine_prop_entries (bfd *output_bfd,
				 asection *sxtlit,
				 asection *sgotloc)
{
  bfd_byte *contents;
  property_table_entry *table;
  bfd_size_type section_size, sgotloc_size;
  bfd_vma offset;
  int n, m, num;

  section_size = sxtlit->size;
  BFD_ASSERT (section_size % 8 == 0);
  num = section_size / 8;

  sgotloc_size = sgotloc->size;
  if (sgotloc_size != section_size)
    {
      (*_bfd_error_handler)
	(_("internal inconsistency in size of .got.loc section"));
      return -1;
    }

  table = bfd_malloc (num * sizeof (property_table_entry));
  if (table == 0)
    return -1;

  /* The ".xt.lit.plt" section has the SEC_IN_MEMORY flag set and this
     propagates to the output section, where it doesn't really apply and
     where it breaks the following call to bfd_malloc_and_get_section.  */
  sxtlit->flags &= ~SEC_IN_MEMORY;

  if (!bfd_malloc_and_get_section (output_bfd, sxtlit, &contents))
    {
      if (contents != 0)
	free (contents);
      free (table);
      return -1;
    }

  /* There should never be any relocations left at this point, so this
     is quite a bit easier than what is done during relaxation.  */

  /* Copy the raw contents into a property table array and sort it.  */
  offset = 0;
  for (n = 0; n < num; n++)
    {
      table[n].address = bfd_get_32 (output_bfd, &contents[offset]);
      table[n].size = bfd_get_32 (output_bfd, &contents[offset + 4]);
      offset += 8;
    }
  qsort (table, num, sizeof (property_table_entry), property_table_compare);

  for (n = 0; n < num; n++)
    {
      bfd_boolean remove = FALSE;

      if (table[n].size == 0)
	remove = TRUE;
      else if (n > 0 &&
	       (table[n-1].address + table[n-1].size == table[n].address))
	{
	  table[n-1].size += table[n].size;
	  remove = TRUE;
	}

      if (remove)
	{
	  for (m = n; m < num - 1; m++)
	    {
	      table[m].address = table[m+1].address;
	      table[m].size = table[m+1].size;
	    }

	  n--;
	  num--;
	}
    }

  /* Copy the data back to the raw contents.  */
  offset = 0;
  for (n = 0; n < num; n++)
    {
      bfd_put_32 (output_bfd, table[n].address, &contents[offset]);
      bfd_put_32 (output_bfd, table[n].size, &contents[offset + 4]);
      offset += 8;
    }

  /* Clear the removed bytes.  */
  if ((bfd_size_type) (num * 8) < section_size)
    memset (&contents[num * 8], 0, section_size - num * 8);

  if (! bfd_set_section_contents (output_bfd, sxtlit, contents, 0,
				  section_size))
    return -1;

  /* Copy the contents to ".got.loc".  */
  memcpy (sgotloc->contents, contents, section_size);

  free (contents);
  free (table);
  return num;
}


/* Finish up the dynamic sections.  */

static bfd_boolean
elf_xtensa_finish_dynamic_sections (bfd *output_bfd,
				    struct bfd_link_info *info)
{
  bfd *dynobj;
  asection *sdyn, *srelplt, *sgot, *sxtlit, *sgotloc;
  Elf32_External_Dyn *dyncon, *dynconend;
  int num_xtlit_entries;

  if (! elf_hash_table (info)->dynamic_sections_created)
    return TRUE;

  dynobj = elf_hash_table (info)->dynobj;
  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
  BFD_ASSERT (sdyn != NULL);

  /* Set the first entry in the global offset table to the address of
     the dynamic section.  */
  sgot = bfd_get_section_by_name (dynobj, ".got");
  if (sgot)
    {
      BFD_ASSERT (sgot->size == 4);
      if (sdyn == NULL)
	bfd_put_32 (output_bfd, 0, sgot->contents);
      else
	bfd_put_32 (output_bfd,
		    sdyn->output_section->vma + sdyn->output_offset,
		    sgot->contents);
    }

  srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
  if (srelplt && srelplt->size != 0)
    {
      asection *sgotplt, *srelgot, *spltlittbl;
      int chunk, plt_chunks, plt_entries;
      Elf_Internal_Rela irela;
      bfd_byte *loc;
      unsigned rtld_reloc;

      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");;
      BFD_ASSERT (srelgot != NULL);

      spltlittbl = bfd_get_section_by_name (dynobj, ".xt.lit.plt");
      BFD_ASSERT (spltlittbl != NULL);

      /* Find the first XTENSA_RTLD relocation.  Presumably the rest
	 of them follow immediately after....  */
      for (rtld_reloc = 0; rtld_reloc < srelgot->reloc_count; rtld_reloc++)
	{
	  loc = srelgot->contents + rtld_reloc * sizeof (Elf32_External_Rela);
	  bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
	  if (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD)
	    break;
	}
      BFD_ASSERT (rtld_reloc < srelgot->reloc_count);

      plt_entries = srelplt->size / sizeof (Elf32_External_Rela);
      plt_chunks =
	(plt_entries + PLT_ENTRIES_PER_CHUNK - 1) / PLT_ENTRIES_PER_CHUNK;

      for (chunk = 0; chunk < plt_chunks; chunk++)
	{
	  int chunk_entries = 0;

	  sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk);
	  BFD_ASSERT (sgotplt != NULL);

	  /* Emit special RTLD relocations for the first two entries in
	     each chunk of the .got.plt section.  */

	  loc = srelgot->contents + rtld_reloc * sizeof (Elf32_External_Rela);
	  bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
	  BFD_ASSERT (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD);
	  irela.r_offset = (sgotplt->output_section->vma
			    + sgotplt->output_offset);
	  irela.r_addend = 1; /* tell rtld to set value to resolver function */
	  bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
	  rtld_reloc += 1;
	  BFD_ASSERT (rtld_reloc <= srelgot->reloc_count);

	  /* Next literal immediately follows the first.  */
	  loc += sizeof (Elf32_External_Rela);
	  bfd_elf32_swap_reloca_in (output_bfd, loc, &irela);
	  BFD_ASSERT (ELF32_R_TYPE (irela.r_info) == R_XTENSA_RTLD);
	  irela.r_offset = (sgotplt->output_section->vma
			    + sgotplt->output_offset + 4);
	  /* Tell rtld to set value to object's link map.  */
	  irela.r_addend = 2;
	  bfd_elf32_swap_reloca_out (output_bfd, &irela, loc);
	  rtld_reloc += 1;
	  BFD_ASSERT (rtld_reloc <= srelgot->reloc_count);

	  /* Fill in the literal table.  */
	  if (chunk < plt_chunks - 1)
	    chunk_entries = PLT_ENTRIES_PER_CHUNK;
	  else
	    chunk_entries = plt_entries - (chunk * PLT_ENTRIES_PER_CHUNK);

	  BFD_ASSERT ((unsigned) (chunk + 1) * 8 <= spltlittbl->size);
	  bfd_put_32 (output_bfd,
		      sgotplt->output_section->vma + sgotplt->output_offset,
		      spltlittbl->contents + (chunk * 8) + 0);
	  bfd_put_32 (output_bfd,
		      8 + (chunk_entries * 4),
		      spltlittbl->contents + (chunk * 8) + 4);
	}

      /* All the dynamic relocations have been emitted at this point.
	 Make sure the relocation sections are the correct size.  */
      if (srelgot->size != (sizeof (Elf32_External_Rela)
			    * srelgot->reloc_count)
	  || srelplt->size != (sizeof (Elf32_External_Rela)
			       * srelplt->reloc_count))
	abort ();

     /* The .xt.lit.plt section has just been modified.  This must
	happen before the code below which combines adjacent literal
	table entries, and the .xt.lit.plt contents have to be forced to
	the output here.  */
      if (! bfd_set_section_contents (output_bfd,
				      spltlittbl->output_section,
				      spltlittbl->contents,
				      spltlittbl->output_offset,
				      spltlittbl->size))
	return FALSE;
      /* Clear SEC_HAS_CONTENTS so the contents won't be output again.  */
      spltlittbl->flags &= ~SEC_HAS_CONTENTS;
    }

  /* Combine adjacent literal table entries.  */
  BFD_ASSERT (! info->relocatable);
  sxtlit = bfd_get_section_by_name (output_bfd, ".xt.lit");
  sgotloc = bfd_get_section_by_name (dynobj, ".got.loc");
  BFD_ASSERT (sxtlit && sgotloc);
  num_xtlit_entries =
    elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc);
  if (num_xtlit_entries < 0)
    return FALSE;

  dyncon = (Elf32_External_Dyn *) sdyn->contents;
  dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
  for (; dyncon < dynconend; dyncon++)
    {
      Elf_Internal_Dyn dyn;
      const char *name;
      asection *s;

      bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);

      switch (dyn.d_tag)
	{
	default:
	  break;

	case DT_XTENSA_GOT_LOC_SZ:
	  dyn.d_un.d_val = num_xtlit_entries;
	  break;

	case DT_XTENSA_GOT_LOC_OFF:
	  name = ".got.loc";
	  goto get_vma;
	case DT_PLTGOT:
	  name = ".got";
	  goto get_vma;
	case DT_JMPREL:
	  name = ".rela.plt";
	get_vma:
	  s = bfd_get_section_by_name (output_bfd, name);
	  BFD_ASSERT (s);
	  dyn.d_un.d_ptr = s->vma;
	  break;

	case DT_PLTRELSZ:
	  s = bfd_get_section_by_name (output_bfd, ".rela.plt");
	  BFD_ASSERT (s);
	  dyn.d_un.d_val = s->size;
	  break;

	case DT_RELASZ:
	  /* Adjust RELASZ to not include JMPREL.  This matches what
	     glibc expects and what is done for several other ELF
	     targets (e.g., i386, alpha), but the "correct" behavior
	     seems to be unresolved.  Since the linker script arranges
	     for .rela.plt to follow all other relocation sections, we
	     don't have to worry about changing the DT_RELA entry.  */
	  s = bfd_get_section_by_name (output_bfd, ".rela.plt");
	  if (s)
	    dyn.d_un.d_val -= s->size;
	  break;
	}

      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
    }

  return TRUE;
}


/* Functions for dealing with the e_flags field.  */

/* Merge backend specific data from an object file to the output
   object file when linking.  */

static bfd_boolean
elf_xtensa_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
{
  unsigned out_mach, in_mach;
  flagword out_flag, in_flag;

  /* Check if we have the same endianess.  */
  if (!_bfd_generic_verify_endian_match (ibfd, obfd))
    return FALSE;

  /* Don't even pretend to support mixed-format linking.  */
  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
    return FALSE;

  out_flag = elf_elfheader (obfd)->e_flags;
  in_flag = elf_elfheader (ibfd)->e_flags;

  out_mach = out_flag & EF_XTENSA_MACH;
  in_mach = in_flag & EF_XTENSA_MACH;
  if (out_mach != in_mach)
    {
      (*_bfd_error_handler)
	(_("%B: incompatible machine type. Output is 0x%x. Input is 0x%x"),
	 ibfd, out_mach, in_mach);
      bfd_set_error (bfd_error_wrong_format);
      return FALSE;
    }

  if (! elf_flags_init (obfd))
    {
      elf_flags_init (obfd) = TRUE;
      elf_elfheader (obfd)->e_flags = in_flag;

      if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
	  && bfd_get_arch_info (obfd)->the_default)
	return bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
				  bfd_get_mach (ibfd));

      return TRUE;
    }

  if ((out_flag & EF_XTENSA_XT_INSN) != (in_flag & EF_XTENSA_XT_INSN)) 
    elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_INSN);

  if ((out_flag & EF_XTENSA_XT_LIT) != (in_flag & EF_XTENSA_XT_LIT)) 
    elf_elfheader (obfd)->e_flags &= (~ EF_XTENSA_XT_LIT);

  return TRUE;
}


static bfd_boolean
elf_xtensa_set_private_flags (bfd *abfd, flagword flags)
{
  BFD_ASSERT (!elf_flags_init (abfd)
	      || elf_elfheader (abfd)->e_flags == flags);

  elf_elfheader (abfd)->e_flags |= flags;
  elf_flags_init (abfd) = TRUE;

  return TRUE;
}


static bfd_boolean
elf_xtensa_print_private_bfd_data (bfd *abfd, void *farg)
{
  FILE *f = (FILE *) farg;
  flagword e_flags = elf_elfheader (abfd)->e_flags;

  fprintf (f, "\nXtensa header:\n");
  if ((e_flags & EF_XTENSA_MACH) == E_XTENSA_MACH)
    fprintf (f, "\nMachine     = Base\n");
  else
    fprintf (f, "\nMachine Id  = 0x%x\n", e_flags & EF_XTENSA_MACH);

  fprintf (f, "Insn tables = %s\n",
	   (e_flags & EF_XTENSA_XT_INSN) ? "true" : "false");

  fprintf (f, "Literal tables = %s\n",
	   (e_flags & EF_XTENSA_XT_LIT) ? "true" : "false");

  return _bfd_elf_print_private_bfd_data (abfd, farg);
}


/* Set the right machine number for an Xtensa ELF file.  */

static bfd_boolean
elf_xtensa_object_p (bfd *abfd)
{
  int mach;
  unsigned long arch = elf_elfheader (abfd)->e_flags & EF_XTENSA_MACH;

  switch (arch)
    {
    case E_XTENSA_MACH:
      mach = bfd_mach_xtensa;
      break;
    default:
      return FALSE;
    }

  (void) bfd_default_set_arch_mach (abfd, bfd_arch_xtensa, mach);
  return TRUE;
}


/* The final processing done just before writing out an Xtensa ELF object
   file.  This gets the Xtensa architecture right based on the machine
   number.  */

static void
elf_xtensa_final_write_processing (bfd *abfd,
				   bfd_boolean linker ATTRIBUTE_UNUSED)
{
  int mach;
  unsigned long val;

  switch (mach = bfd_get_mach (abfd))
    {
    case bfd_mach_xtensa:
      val = E_XTENSA_MACH;
      break;
    default:
      return;
    }

  elf_elfheader (abfd)->e_flags &=  (~ EF_XTENSA_MACH);
  elf_elfheader (abfd)->e_flags |= val;
}


static enum elf_reloc_type_class
elf_xtensa_reloc_type_class (const Elf_Internal_Rela *rela)
{
  switch ((int) ELF32_R_TYPE (rela->r_info))
    {
    case R_XTENSA_RELATIVE:
      return reloc_class_relative;
    case R_XTENSA_JMP_SLOT:
      return reloc_class_plt;
    default:
      return reloc_class_normal;
    }
}


static bfd_boolean
elf_xtensa_discard_info_for_section (bfd *abfd,
				     struct elf_reloc_cookie *cookie,
				     struct bfd_link_info *info,
				     asection *sec)
{
  bfd_byte *contents;
  bfd_vma section_size;
  bfd_vma offset, actual_offset;
  size_t removed_bytes = 0;

  section_size = sec->size;
  if (section_size == 0 || section_size % 8 != 0)
    return FALSE;

  if (sec->output_section
      && bfd_is_abs_section (sec->output_section))
    return FALSE;

  contents = retrieve_contents (abfd, sec, info->keep_memory);
  if (!contents)
    return FALSE;

  cookie->rels = retrieve_internal_relocs (abfd, sec, info->keep_memory);
  if (!cookie->rels)
    {
      release_contents (sec, contents);
      return FALSE;
    }

  cookie->rel = cookie->rels;
  cookie->relend = cookie->rels + sec->reloc_count;

  for (offset = 0; offset < section_size; offset += 8)
    {
      actual_offset = offset - removed_bytes;

      /* The ...symbol_deleted_p function will skip over relocs but it
	 won't adjust their offsets, so do that here.  */
      while (cookie->rel < cookie->relend
	     && cookie->rel->r_offset < offset)
	{
	  cookie->rel->r_offset -= removed_bytes;
	  cookie->rel++;
	}

      while (cookie->rel < cookie->relend
	     && cookie->rel->r_offset == offset)
	{
	  if (bfd_elf_reloc_symbol_deleted_p (offset, cookie))
	    {
	      /* Remove the table entry.  (If the reloc type is NONE, then
		 the entry has already been merged with another and deleted
		 during relaxation.)  */
	      if (ELF32_R_TYPE (cookie->rel->r_info) != R_XTENSA_NONE)
		{
		  /* Shift the contents up.  */
		  if (offset + 8 < section_size)
		    memmove (&contents[actual_offset],
			     &contents[actual_offset+8],
			     section_size - offset - 8);
		  removed_bytes += 8;
		}

	      /* Remove this relocation.  */
	      cookie->rel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
	    }

	  /* Adjust the relocation offset for previous removals.  This
	     should not be done before calling ...symbol_deleted_p
	     because it might mess up the offset comparisons there.
	     Make sure the offset doesn't underflow in the case where
	     the first entry is removed.  */
	  if (cookie->rel->r_offset >= removed_bytes)
	    cookie->rel->r_offset -= removed_bytes;
	  else
	    cookie->rel->r_offset = 0;

	  cookie->rel++;
	}
    }

  if (removed_bytes != 0)
    {
      /* Adjust any remaining relocs (shouldn't be any).  */
      for (; cookie->rel < cookie->relend; cookie->rel++)
	{
	  if (cookie->rel->r_offset >= removed_bytes)
	    cookie->rel->r_offset -= removed_bytes;
	  else
	    cookie->rel->r_offset = 0;
	}

      /* Clear the removed bytes.  */
      memset (&contents[section_size - removed_bytes], 0, removed_bytes);

      pin_contents (sec, contents);
      pin_internal_relocs (sec, cookie->rels);

      /* Shrink size.  */
      sec->size = section_size - removed_bytes;

      if (xtensa_is_littable_section (sec))
	{
	  bfd *dynobj = elf_hash_table (info)->dynobj;
	  if (dynobj)
	    {
	      asection *sgotloc =
		bfd_get_section_by_name (dynobj, ".got.loc");
	      if (sgotloc)
		sgotloc->size -= removed_bytes;
	    }
	}
    }
  else
    {
      release_contents (sec, contents);
      release_internal_relocs (sec, cookie->rels);
    }

  return (removed_bytes != 0);
}


static bfd_boolean
elf_xtensa_discard_info (bfd *abfd,
			 struct elf_reloc_cookie *cookie,
			 struct bfd_link_info *info)
{
  asection *sec;
  bfd_boolean changed = FALSE;

  for (sec = abfd->sections; sec != NULL; sec = sec->next)
    {
      if (xtensa_is_property_section (sec))
	{
	  if (elf_xtensa_discard_info_for_section (abfd, cookie, info, sec))
	    changed = TRUE;
	}
    }

  return changed;
}


static bfd_boolean
elf_xtensa_ignore_discarded_relocs (asection *sec)
{
  return xtensa_is_property_section (sec);
}


/* Support for core dump NOTE sections.  */

static bfd_boolean
elf_xtensa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
  int offset;
  unsigned int size;

  /* The size for Xtensa is variable, so don't try to recognize the format
     based on the size.  Just assume this is GNU/Linux.  */

  /* pr_cursig */
  elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);

  /* pr_pid */
  elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);

  /* pr_reg */
  offset = 72;
  size = note->descsz - offset - 4;

  /* Make a ".reg/999" section.  */
  return _bfd_elfcore_make_pseudosection (abfd, ".reg",
					  size, note->descpos + offset);
}


static bfd_boolean
elf_xtensa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
  switch (note->descsz)
    {
      default:
	return FALSE;

      case 128:		/* GNU/Linux elf_prpsinfo */
	elf_tdata (abfd)->core_program
	 = _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
	elf_tdata (abfd)->core_command
	 = _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
    }

  /* Note that for some reason, a spurious space is tacked
     onto the end of the args in some (at least one anyway)
     implementations, so strip it off if it exists.  */

  {
    char *command = elf_tdata (abfd)->core_command;
    int n = strlen (command);

    if (0 < n && command[n - 1] == ' ')
      command[n - 1] = '\0';
  }

  return TRUE;
}


/* Generic Xtensa configurability stuff.  */

static xtensa_opcode callx0_op = XTENSA_UNDEFINED;
static xtensa_opcode callx4_op = XTENSA_UNDEFINED;
static xtensa_opcode callx8_op = XTENSA_UNDEFINED;
static xtensa_opcode callx12_op = XTENSA_UNDEFINED;
static xtensa_opcode call0_op = XTENSA_UNDEFINED;
static xtensa_opcode call4_op = XTENSA_UNDEFINED;
static xtensa_opcode call8_op = XTENSA_UNDEFINED;
static xtensa_opcode call12_op = XTENSA_UNDEFINED;

static void
init_call_opcodes (void)
{
  if (callx0_op == XTENSA_UNDEFINED)
    {
      callx0_op  = xtensa_opcode_lookup (xtensa_default_isa, "callx0");
      callx4_op  = xtensa_opcode_lookup (xtensa_default_isa, "callx4");
      callx8_op  = xtensa_opcode_lookup (xtensa_default_isa, "callx8");
      callx12_op = xtensa_opcode_lookup (xtensa_default_isa, "callx12");
      call0_op   = xtensa_opcode_lookup (xtensa_default_isa, "call0");
      call4_op   = xtensa_opcode_lookup (xtensa_default_isa, "call4");
      call8_op   = xtensa_opcode_lookup (xtensa_default_isa, "call8");
      call12_op  = xtensa_opcode_lookup (xtensa_default_isa, "call12");
    }
}


static bfd_boolean
is_indirect_call_opcode (xtensa_opcode opcode)
{
  init_call_opcodes ();
  return (opcode == callx0_op
	  || opcode == callx4_op
	  || opcode == callx8_op
	  || opcode == callx12_op);
}


static bfd_boolean
is_direct_call_opcode (xtensa_opcode opcode)
{
  init_call_opcodes ();
  return (opcode == call0_op
	  || opcode == call4_op
	  || opcode == call8_op
	  || opcode == call12_op);
}


static bfd_boolean
is_windowed_call_opcode (xtensa_opcode opcode)
{
  init_call_opcodes ();
  return (opcode == call4_op
	  || opcode == call8_op
	  || opcode == call12_op
	  || opcode == callx4_op
	  || opcode == callx8_op
	  || opcode == callx12_op);
}


static xtensa_opcode
get_const16_opcode (void)
{
  static bfd_boolean done_lookup = FALSE;
  static xtensa_opcode const16_opcode = XTENSA_UNDEFINED;
  if (!done_lookup)
    {
      const16_opcode = xtensa_opcode_lookup (xtensa_default_isa, "const16");
      done_lookup = TRUE;
    }
  return const16_opcode;
}


static xtensa_opcode
get_l32r_opcode (void)
{
  static xtensa_opcode l32r_opcode = XTENSA_UNDEFINED;
  static bfd_boolean done_lookup = FALSE;

  if (!done_lookup)
    {
      l32r_opcode = xtensa_opcode_lookup (xtensa_default_isa, "l32r");
      done_lookup = TRUE;
    }
  return l32r_opcode;
}


static bfd_vma
l32r_offset (bfd_vma addr, bfd_vma pc)
{
  bfd_vma offset;

  offset = addr - ((pc+3) & -4);
  BFD_ASSERT ((offset & ((1 << 2) - 1)) == 0);
  offset = (signed int) offset >> 2;
  BFD_ASSERT ((signed int) offset >> 16 == -1);
  return offset;
}


static int
get_relocation_opnd (xtensa_opcode opcode, int r_type)
{
  xtensa_isa isa = xtensa_default_isa;
  int last_immed, last_opnd, opi;

  if (opcode == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;

  /* Find the last visible PC-relative immediate operand for the opcode.
     If there are no PC-relative immediates, then choose the last visible
     immediate; otherwise, fail and return XTENSA_UNDEFINED.  */
  last_immed = XTENSA_UNDEFINED;
  last_opnd = xtensa_opcode_num_operands (isa, opcode);
  for (opi = last_opnd - 1; opi >= 0; opi--)
    {
      if (xtensa_operand_is_visible (isa, opcode, opi) == 0)
	continue;
      if (xtensa_operand_is_PCrelative (isa, opcode, opi) == 1)
	{
	  last_immed = opi;
	  break;
	}
      if (last_immed == XTENSA_UNDEFINED
	  && xtensa_operand_is_register (isa, opcode, opi) == 0)
	last_immed = opi;
    }
  if (last_immed < 0)
    return XTENSA_UNDEFINED;

  /* If the operand number was specified in an old-style relocation,
     check for consistency with the operand computed above.  */
  if (r_type >= R_XTENSA_OP0 && r_type <= R_XTENSA_OP2)
    {
      int reloc_opnd = r_type - R_XTENSA_OP0;
      if (reloc_opnd != last_immed)
	return XTENSA_UNDEFINED;
    }

  return last_immed;
}


int
get_relocation_slot (int r_type)
{
  switch (r_type)
    {
    case R_XTENSA_OP0:
    case R_XTENSA_OP1:
    case R_XTENSA_OP2:
      return 0;

    default:
      if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP)
	return r_type - R_XTENSA_SLOT0_OP;
      if (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT)
	return r_type - R_XTENSA_SLOT0_ALT;
      break;
    }

  return XTENSA_UNDEFINED;
}


/* Get the opcode for a relocation.  */

static xtensa_opcode
get_relocation_opcode (bfd *abfd,
		       asection *sec,
		       bfd_byte *contents,
		       Elf_Internal_Rela *irel)
{
  static xtensa_insnbuf ibuff = NULL;
  static xtensa_insnbuf sbuff = NULL;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt;
  int slot;

  if (contents == NULL)
    return XTENSA_UNDEFINED;

  if (bfd_get_section_limit (abfd, sec) <= irel->r_offset)
    return XTENSA_UNDEFINED;

  if (ibuff == NULL)
    {
      ibuff = xtensa_insnbuf_alloc (isa);
      sbuff = xtensa_insnbuf_alloc (isa);
    }

  /* Decode the instruction.  */
  xtensa_insnbuf_from_chars (isa, ibuff, &contents[irel->r_offset],
			     sec->size - irel->r_offset);
  fmt = xtensa_format_decode (isa, ibuff);
  slot = get_relocation_slot (ELF32_R_TYPE (irel->r_info));
  if (slot == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;
  xtensa_format_get_slot (isa, fmt, slot, ibuff, sbuff);
  return xtensa_opcode_decode (isa, fmt, slot, sbuff);
}


bfd_boolean
is_l32r_relocation (bfd *abfd,
		    asection *sec,
		    bfd_byte *contents,
		    Elf_Internal_Rela *irel)
{
  xtensa_opcode opcode;
  if (!is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
    return FALSE;
  opcode = get_relocation_opcode (abfd, sec, contents, irel);
  return (opcode == get_l32r_opcode ());
}


static bfd_size_type
get_asm_simplify_size (bfd_byte *contents,
		       bfd_size_type content_len,
		       bfd_size_type offset)
{
  bfd_size_type insnlen, size = 0;

  /* Decode the size of the next two instructions.  */
  insnlen = insn_decode_len (contents, content_len, offset);
  if (insnlen == 0)
    return 0;

  size += insnlen;
  
  insnlen = insn_decode_len (contents, content_len, offset + size);
  if (insnlen == 0)
    return 0;

  size += insnlen;
  return size;
}


bfd_boolean
is_alt_relocation (int r_type)
{
  return (r_type >= R_XTENSA_SLOT0_ALT
	  && r_type <= R_XTENSA_SLOT14_ALT);
}


bfd_boolean
is_operand_relocation (int r_type)
{
  switch (r_type)
    {
    case R_XTENSA_OP0:
    case R_XTENSA_OP1:
    case R_XTENSA_OP2:
      return TRUE;

    default:
      if (r_type >= R_XTENSA_SLOT0_OP && r_type <= R_XTENSA_SLOT14_OP)
	return TRUE;
      if (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT)
	return TRUE;
      break;
    }

  return FALSE;
}

      
#define MIN_INSN_LENGTH 2

/* Return 0 if it fails to decode.  */

bfd_size_type
insn_decode_len (bfd_byte *contents,
		 bfd_size_type content_len,
		 bfd_size_type offset)
{
  int insn_len;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt;
  static xtensa_insnbuf ibuff = NULL;

  if (offset + MIN_INSN_LENGTH > content_len)
    return 0;

  if (ibuff == NULL)
    ibuff = xtensa_insnbuf_alloc (isa);
  xtensa_insnbuf_from_chars (isa, ibuff, &contents[offset],
			     content_len - offset);
  fmt = xtensa_format_decode (isa, ibuff);
  if (fmt == XTENSA_UNDEFINED)
    return 0;
  insn_len = xtensa_format_length (isa, fmt);
  if (insn_len ==  XTENSA_UNDEFINED)
    return 0;
  return insn_len;
}


/* Decode the opcode for a single slot instruction.
   Return 0 if it fails to decode or the instruction is multi-slot.  */

xtensa_opcode
insn_decode_opcode (bfd_byte *contents,
		    bfd_size_type content_len,
		    bfd_size_type offset,
		    int slot)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt;
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;

  if (offset + MIN_INSN_LENGTH > content_len)
    return XTENSA_UNDEFINED;

  if (insnbuf == NULL)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
			     content_len - offset);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;

  if (slot >= xtensa_format_num_slots (isa, fmt))
    return XTENSA_UNDEFINED;

  xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
  return xtensa_opcode_decode (isa, fmt, slot, slotbuf);
}


/* The offset is the offset in the contents.
   The address is the address of that offset.  */

static bfd_boolean
check_branch_target_aligned (bfd_byte *contents,
			     bfd_size_type content_length,
			     bfd_vma offset,
			     bfd_vma address)
{
  bfd_size_type insn_len = insn_decode_len (contents, content_length, offset);
  if (insn_len == 0)
    return FALSE;
  return check_branch_target_aligned_address (address, insn_len);
}


static bfd_boolean
check_loop_aligned (bfd_byte *contents,
		    bfd_size_type content_length,
		    bfd_vma offset,
		    bfd_vma address)
{
  bfd_size_type loop_len, insn_len;
  xtensa_opcode opcode =
    insn_decode_opcode (contents, content_length, offset, 0);
  BFD_ASSERT (opcode != XTENSA_UNDEFINED);
  if (opcode != XTENSA_UNDEFINED)
    return FALSE;
  BFD_ASSERT (xtensa_opcode_is_loop (xtensa_default_isa, opcode));
  if (!xtensa_opcode_is_loop (xtensa_default_isa, opcode))
    return FALSE;

  loop_len = insn_decode_len (contents, content_length, offset);
  BFD_ASSERT (loop_len != 0);
  if (loop_len == 0)
    return FALSE;

  insn_len = insn_decode_len (contents, content_length, offset + loop_len);
  BFD_ASSERT (insn_len != 0);
  if (insn_len == 0)
    return FALSE;

  return check_branch_target_aligned_address (address + loop_len, insn_len);
}


static bfd_boolean
check_branch_target_aligned_address (bfd_vma addr, int len)
{
  if (len == 8)
    return (addr % 8 == 0);
  return ((addr >> 2) == ((addr + len - 1) >> 2));
}


/* Instruction widening and narrowing.  */

/* When FLIX is available we need to access certain instructions only
   when they are 16-bit or 24-bit instructions.  This table caches
   information about such instructions by walking through all the
   opcodes and finding the smallest single-slot format into which each
   can be encoded.  */

static xtensa_format *op_single_fmt_table = NULL;


static void
init_op_single_format_table (void)
{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_insnbuf ibuf;
  xtensa_opcode opcode;
  xtensa_format fmt;
  int num_opcodes;

  if (op_single_fmt_table)
    return;

  ibuf = xtensa_insnbuf_alloc (isa);
  num_opcodes = xtensa_isa_num_opcodes (isa);

  op_single_fmt_table = (xtensa_format *)
    bfd_malloc (sizeof (xtensa_format) * num_opcodes);
  for (opcode = 0; opcode < num_opcodes; opcode++)
    {
      op_single_fmt_table[opcode] = XTENSA_UNDEFINED;
      for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++)
	{
	  if (xtensa_format_num_slots (isa, fmt) == 1
	      && xtensa_opcode_encode (isa, fmt, 0, ibuf, opcode) == 0)
	    {
	      xtensa_opcode old_fmt = op_single_fmt_table[opcode];
	      int fmt_length = xtensa_format_length (isa, fmt);
	      if (old_fmt == XTENSA_UNDEFINED
		  || fmt_length < xtensa_format_length (isa, old_fmt))
		op_single_fmt_table[opcode] = fmt;
	    }
	}
    }
  xtensa_insnbuf_free (isa, ibuf);
}


static xtensa_format
get_single_format (xtensa_opcode opcode)
{
  init_op_single_format_table ();
  return op_single_fmt_table[opcode];
}


/* For the set of narrowable instructions we do NOT include the
   narrowings beqz -> beqz.n or bnez -> bnez.n because of complexities
   involved during linker relaxation that may require these to
   re-expand in some conditions.  Also, the narrowing "or" -> mov.n
   requires special case code to ensure it only works when op1 == op2.  */

struct string_pair
{
  const char *wide;
  const char *narrow;
};

struct string_pair narrowable[] =
{
  { "add", "add.n" },
  { "addi", "addi.n" },
  { "addmi", "addi.n" },
  { "l32i", "l32i.n" },
  { "movi", "movi.n" },
  { "ret", "ret.n" },
  { "retw", "retw.n" },
  { "s32i", "s32i.n" },
  { "or", "mov.n" } /* special case only when op1 == op2 */
};

struct string_pair widenable[] =
{
  { "add", "add.n" },
  { "addi", "addi.n" },
  { "addmi", "addi.n" },
  { "beqz", "beqz.n" },
  { "bnez", "bnez.n" },
  { "l32i", "l32i.n" },
  { "movi", "movi.n" },
  { "ret", "ret.n" },
  { "retw", "retw.n" },
  { "s32i", "s32i.n" },
  { "or", "mov.n" } /* special case only when op1 == op2 */
};


/* Attempt to narrow an instruction.  Return true if the narrowing is
   valid.  If the do_it parameter is non-zero, then perform the action
   in-place directly into the contents.  Otherwise, do not modify the
   contents.  The set of valid narrowing are specified by a string table
   but require some special case operand checks in some cases.  */

static bfd_boolean
narrow_instruction (bfd_byte *contents,
		    bfd_size_type content_length,
		    bfd_size_type offset,
		    bfd_boolean do_it)
{
  xtensa_opcode opcode;
  bfd_size_type insn_len, opi;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt, o_fmt;

  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  static xtensa_insnbuf o_insnbuf = NULL;
  static xtensa_insnbuf o_slotbuf = NULL;

  if (insnbuf == NULL)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
      o_insnbuf = xtensa_insnbuf_alloc (isa);
      o_slotbuf = xtensa_insnbuf_alloc (isa);
    }

  BFD_ASSERT (offset < content_length);

  if (content_length < 2)
    return FALSE;

  /* We will hand-code a few of these for a little while.
     These have all been specified in the assembler aleady.  */
  xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
			     content_length - offset);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (xtensa_format_num_slots (isa, fmt) != 1)
    return FALSE;

  if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0)
    return FALSE;

  opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
  if (opcode == XTENSA_UNDEFINED)
    return FALSE;
  insn_len = xtensa_format_length (isa, fmt);
  if (insn_len > content_length)
    return FALSE;

  for (opi = 0; opi < (sizeof (narrowable)/sizeof (struct string_pair)); ++opi)
    {
      bfd_boolean is_or = (strcmp ("or", narrowable[opi].wide) == 0);

      if (opcode == xtensa_opcode_lookup (isa, narrowable[opi].wide))
	{
	  uint32 value, newval;
	  int i, operand_count, o_operand_count;
	  xtensa_opcode o_opcode;

	  /* Address does not matter in this case.  We might need to
	     fix it to handle branches/jumps.  */
	  bfd_vma self_address = 0;

	  o_opcode = xtensa_opcode_lookup (isa, narrowable[opi].narrow);
	  if (o_opcode == XTENSA_UNDEFINED)
	    return FALSE;
	  o_fmt = get_single_format (o_opcode);
	  if (o_fmt == XTENSA_UNDEFINED)
	    return FALSE;

	  if (xtensa_format_length (isa, fmt) != 3
	      || xtensa_format_length (isa, o_fmt) != 2)
	    return FALSE;

	  xtensa_format_encode (isa, o_fmt, o_insnbuf);
	  operand_count = xtensa_opcode_num_operands (isa, opcode);
	  o_operand_count = xtensa_opcode_num_operands (isa, o_opcode);

	  if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0)
	    return FALSE;

	  if (!is_or)
	    {
	      if (xtensa_opcode_num_operands (isa, o_opcode) != operand_count)
		return FALSE;
	    }
	  else
	    {
	      uint32 rawval0, rawval1, rawval2;

	      if (o_operand_count + 1 != operand_count)
		return FALSE;
	      if (xtensa_operand_get_field (isa, opcode, 0,
					    fmt, 0, slotbuf, &rawval0) != 0)
		return FALSE;
	      if (xtensa_operand_get_field (isa, opcode, 1,
					    fmt, 0, slotbuf, &rawval1) != 0)
		return FALSE;
	      if (xtensa_operand_get_field (isa, opcode, 2,
					    fmt, 0, slotbuf, &rawval2) != 0)
		return FALSE;

	      if (rawval1 != rawval2)
		return FALSE;
	      if (rawval0 == rawval1) /* it is a nop */
		return FALSE;
	    }

	  for (i = 0; i < o_operand_count; ++i)
	    {
	      if (xtensa_operand_get_field (isa, opcode, i, fmt, 0,
					    slotbuf, &value)
		  || xtensa_operand_decode (isa, opcode, i, &value))
		return FALSE;

	      /* PC-relative branches need adjustment, but
		 the PC-rel operand will always have a relocation.  */
	      newval = value;
	      if (xtensa_operand_do_reloc (isa, o_opcode, i, &newval,
					   self_address)
		  || xtensa_operand_encode (isa, o_opcode, i, &newval)
		  || xtensa_operand_set_field (isa, o_opcode, i, o_fmt, 0,
					       o_slotbuf, newval))
		return FALSE;
	    }

	  if (xtensa_format_set_slot (isa, o_fmt, 0,
				      o_insnbuf, o_slotbuf) != 0)
	    return FALSE;

	  if (do_it)
	    xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset,
				     content_length - offset);
	  return TRUE;
	}
    }
  return FALSE;
}


/* Attempt to widen an instruction.  Return true if the widening is
   valid.  If the do_it parameter is non-zero, then the action should
   be performed inplace into the contents.  Otherwise, do not modify
   the contents.  The set of valid widenings are specified by a string
   table but require some special case operand checks in some
   cases.  */

static bfd_boolean
widen_instruction (bfd_byte *contents,
		   bfd_size_type content_length,
		   bfd_size_type offset,
		   bfd_boolean do_it)
{
  xtensa_opcode opcode;
  bfd_size_type insn_len, opi;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt, o_fmt;

  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  static xtensa_insnbuf o_insnbuf = NULL;
  static xtensa_insnbuf o_slotbuf = NULL;

  if (insnbuf == NULL)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
      o_insnbuf = xtensa_insnbuf_alloc (isa);
      o_slotbuf = xtensa_insnbuf_alloc (isa);
    }

  BFD_ASSERT (offset < content_length);

  if (content_length < 2)
    return FALSE;

  /* We will hand code a few of these for a little while.
     These have all been specified in the assembler aleady.  */
  xtensa_insnbuf_from_chars (isa, insnbuf, &contents[offset],
			     content_length - offset);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (xtensa_format_num_slots (isa, fmt) != 1)
    return FALSE;

  if (xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf) != 0)
    return FALSE;

  opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
  if (opcode == XTENSA_UNDEFINED)
    return FALSE;
  insn_len = xtensa_format_length (isa, fmt);
  if (insn_len > content_length)
    return FALSE;

  for (opi = 0; opi < (sizeof (widenable)/sizeof (struct string_pair)); ++opi)
    {
      bfd_boolean is_or = (strcmp ("or", widenable[opi].wide) == 0);
      bfd_boolean is_branch = (strcmp ("beqz", widenable[opi].wide) == 0
			       || strcmp ("bnez", widenable[opi].wide) == 0);

      if (opcode == xtensa_opcode_lookup (isa, widenable[opi].narrow))
	{
	  uint32 value, newval;
	  int i, operand_count, o_operand_count, check_operand_count;
	  xtensa_opcode o_opcode;

	  /* Address does not matter in this case.  We might need to fix it
	     to handle branches/jumps.  */
	  bfd_vma self_address = 0;

	  o_opcode = xtensa_opcode_lookup (isa, widenable[opi].wide);
	  if (o_opcode == XTENSA_UNDEFINED)
	    return FALSE;
	  o_fmt = get_single_format (o_opcode);
	  if (o_fmt == XTENSA_UNDEFINED)
	    return FALSE;

	  if (xtensa_format_length (isa, fmt) != 2
	      || xtensa_format_length (isa, o_fmt) != 3)
	    return FALSE;

	  xtensa_format_encode (isa, o_fmt, o_insnbuf);
	  operand_count = xtensa_opcode_num_operands (isa, opcode);
	  o_operand_count = xtensa_opcode_num_operands (isa, o_opcode);
	  check_operand_count = o_operand_count;

	  if (xtensa_opcode_encode (isa, o_fmt, 0, o_slotbuf, o_opcode) != 0)
	    return FALSE;

	  if (!is_or)
	    {
	      if (xtensa_opcode_num_operands (isa, o_opcode) != operand_count)
		return FALSE;
	    }
	  else
	    {
	      uint32 rawval0, rawval1;

	      if (o_operand_count != operand_count + 1)
		return FALSE;
	      if (xtensa_operand_get_field (isa, opcode, 0,
					    fmt, 0, slotbuf, &rawval0) != 0)
		return FALSE;
	      if (xtensa_operand_get_field (isa, opcode, 1,
					    fmt, 0, slotbuf, &rawval1) != 0)
		return FALSE;
	      if (rawval0 == rawval1) /* it is a nop */
		return FALSE;
	    }
	  if (is_branch)
	    check_operand_count--;

	  for (i = 0; i < check_operand_count; ++i)
	    {
	      int new_i = i;
	      if (is_or && i == o_operand_count - 1)
		new_i = i - 1;
	      if (xtensa_operand_get_field (isa, opcode, new_i, fmt, 0,
					    slotbuf, &value)
		  || xtensa_operand_decode (isa, opcode, new_i, &value))
		return FALSE;

	      /* PC-relative branches need adjustment, but
		 the PC-rel operand will always have a relocation.  */
	      newval = value;
	      if (xtensa_operand_do_reloc (isa, o_opcode, i, &newval,
					   self_address)
		  || xtensa_operand_encode (isa, o_opcode, i, &newval)
		  || xtensa_operand_set_field (isa, o_opcode, i, o_fmt, 0,
					       o_slotbuf, newval))
		return FALSE;
	    }

	  if (xtensa_format_set_slot (isa, o_fmt, 0, o_insnbuf, o_slotbuf))
	    return FALSE;

	  if (do_it)
	    xtensa_insnbuf_to_chars (isa, o_insnbuf, contents + offset,
				     content_length - offset);
	  return TRUE;
	}
    }
  return FALSE;
}


/* Code for transforming CALLs at link-time.  */

static bfd_reloc_status_type
elf_xtensa_do_asm_simplify (bfd_byte *contents,
			    bfd_vma address,
			    bfd_vma content_length,
			    char **error_message)
{
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  xtensa_format core_format = XTENSA_UNDEFINED;
  xtensa_opcode opcode;
  xtensa_opcode direct_call_opcode;
  xtensa_isa isa = xtensa_default_isa;
  bfd_byte *chbuf = contents + address;
  int opn;

  if (insnbuf == NULL)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  if (content_length < address)
    {
      *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
      return bfd_reloc_other;
    }

  opcode = get_expanded_call_opcode (chbuf, content_length - address, 0);
  direct_call_opcode = swap_callx_for_call_opcode (opcode);
  if (direct_call_opcode == XTENSA_UNDEFINED)
    {
      *error_message = _("Attempt to convert L32R/CALLX to CALL failed");
      return bfd_reloc_other;
    }
  
  /* Assemble a NOP ("or a1, a1, a1") into the 0 byte offset.  */
  core_format = xtensa_format_lookup (isa, "x24");
  opcode = xtensa_opcode_lookup (isa, "or");
  xtensa_opcode_encode (isa, core_format, 0, slotbuf, opcode);
  for (opn = 0; opn < 3; opn++) 
    {
      uint32 regno = 1;
      xtensa_operand_encode (isa, opcode, opn, &regno);
      xtensa_operand_set_field (isa, opcode, opn, core_format, 0,
				slotbuf, regno);
    }
  xtensa_format_encode (isa, core_format, insnbuf);
  xtensa_format_set_slot (isa, core_format, 0, insnbuf, slotbuf);
  xtensa_insnbuf_to_chars (isa, insnbuf, chbuf, content_length - address);

  /* Assemble a CALL ("callN 0") into the 3 byte offset.  */
  xtensa_opcode_encode (isa, core_format, 0, slotbuf, direct_call_opcode);
  xtensa_operand_set_field (isa, opcode, 0, core_format, 0, slotbuf, 0);

  xtensa_format_encode (isa, core_format, insnbuf);
  xtensa_format_set_slot (isa, core_format, 0, insnbuf, slotbuf);
  xtensa_insnbuf_to_chars (isa, insnbuf, chbuf + 3,
			   content_length - address - 3);

  return bfd_reloc_ok;
}


static bfd_reloc_status_type
contract_asm_expansion (bfd_byte *contents,
			bfd_vma content_length,
			Elf_Internal_Rela *irel,
			char **error_message)
{
  bfd_reloc_status_type retval =
    elf_xtensa_do_asm_simplify (contents, irel->r_offset, content_length,
				error_message);

  if (retval != bfd_reloc_ok)
    return bfd_reloc_dangerous;

  /* Update the irel->r_offset field so that the right immediate and
     the right instruction are modified during the relocation.  */
  irel->r_offset += 3;
  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_XTENSA_SLOT0_OP);
  return bfd_reloc_ok;
}


static xtensa_opcode
swap_callx_for_call_opcode (xtensa_opcode opcode)
{
  init_call_opcodes ();

  if (opcode == callx0_op) return call0_op;
  if (opcode == callx4_op) return call4_op;
  if (opcode == callx8_op) return call8_op;
  if (opcode == callx12_op) return call12_op;

  /* Return XTENSA_UNDEFINED if the opcode is not an indirect call.  */
  return XTENSA_UNDEFINED;
}


/* Check if "buf" is pointing to a "L32R aN; CALLX aN" or "CONST16 aN;
   CONST16 aN; CALLX aN" sequence, and if so, return the CALLX opcode.
   If not, return XTENSA_UNDEFINED.  */

#define L32R_TARGET_REG_OPERAND 0
#define CONST16_TARGET_REG_OPERAND 0
#define CALLN_SOURCE_OPERAND 0

static xtensa_opcode 
get_expanded_call_opcode (bfd_byte *buf, int bufsize, bfd_boolean *p_uses_l32r)
{
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  xtensa_format fmt;
  xtensa_opcode opcode;
  xtensa_isa isa = xtensa_default_isa;
  uint32 regno, const16_regno, call_regno;
  int offset = 0;

  if (insnbuf == NULL)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  xtensa_insnbuf_from_chars (isa, insnbuf, buf, bufsize);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED
      || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
    return XTENSA_UNDEFINED;

  opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
  if (opcode == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;

  if (opcode == get_l32r_opcode ())
    {
      if (p_uses_l32r)
	*p_uses_l32r = TRUE;
      if (xtensa_operand_get_field (isa, opcode, L32R_TARGET_REG_OPERAND,
				    fmt, 0, slotbuf, &regno)
	  || xtensa_operand_decode (isa, opcode, L32R_TARGET_REG_OPERAND,
				    &regno))
	return XTENSA_UNDEFINED;
    }
  else if (opcode == get_const16_opcode ())
    {
      if (p_uses_l32r)
	*p_uses_l32r = FALSE;
      if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND,
				    fmt, 0, slotbuf, &regno)
	  || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
				    &regno))
	return XTENSA_UNDEFINED;

      /* Check that the next instruction is also CONST16.  */
      offset += xtensa_format_length (isa, fmt);
      xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset);
      fmt = xtensa_format_decode (isa, insnbuf);
      if (fmt == XTENSA_UNDEFINED
	  || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
	return XTENSA_UNDEFINED;
      opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
      if (opcode != get_const16_opcode ())
	return XTENSA_UNDEFINED;

      if (xtensa_operand_get_field (isa, opcode, CONST16_TARGET_REG_OPERAND,
				    fmt, 0, slotbuf, &const16_regno)
	  || xtensa_operand_decode (isa, opcode, CONST16_TARGET_REG_OPERAND,
				    &const16_regno)
	  || const16_regno != regno)
	return XTENSA_UNDEFINED;
    }
  else
    return XTENSA_UNDEFINED;

  /* Next instruction should be an CALLXn with operand 0 == regno.  */
  offset += xtensa_format_length (isa, fmt);
  xtensa_insnbuf_from_chars (isa, insnbuf, buf + offset, bufsize - offset);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED
      || xtensa_format_get_slot (isa, fmt, 0, insnbuf, slotbuf))
    return XTENSA_UNDEFINED;
  opcode = xtensa_opcode_decode (isa, fmt, 0, slotbuf);
  if (opcode == XTENSA_UNDEFINED 
      || !is_indirect_call_opcode (opcode))
    return XTENSA_UNDEFINED;

  if (xtensa_operand_get_field (isa, opcode, CALLN_SOURCE_OPERAND,
				fmt, 0, slotbuf, &call_regno)
      || xtensa_operand_decode (isa, opcode, CALLN_SOURCE_OPERAND,
				&call_regno))
    return XTENSA_UNDEFINED;

  if (call_regno != regno)
    return XTENSA_UNDEFINED;

  return opcode;
}


/* Data structures used during relaxation.  */

/* r_reloc: relocation values.  */

/* Through the relaxation process, we need to keep track of the values
   that will result from evaluating relocations.  The standard ELF
   relocation structure is not sufficient for this purpose because we're
   operating on multiple input files at once, so we need to know which
   input file a relocation refers to.  The r_reloc structure thus
   records both the input file (bfd) and ELF relocation.

   For efficiency, an r_reloc also contains a "target_offset" field to
   cache the target-section-relative offset value that is represented by
   the relocation.
   
   The r_reloc also contains a virtual offset that allows multiple
   inserted literals to be placed at the same "address" with
   different offsets.  */

typedef struct r_reloc_struct r_reloc;

struct r_reloc_struct
{
  bfd *abfd;
  Elf_Internal_Rela rela;
  bfd_vma target_offset;
  bfd_vma virtual_offset;
};


/* The r_reloc structure is included by value in literal_value, but not
   every literal_value has an associated relocation -- some are simple
   constants.  In such cases, we set all the fields in the r_reloc
   struct to zero.  The r_reloc_is_const function should be used to
   detect this case.  */

static bfd_boolean
r_reloc_is_const (const r_reloc *r_rel)
{
  return (r_rel->abfd == NULL);
}


static bfd_vma
r_reloc_get_target_offset (const r_reloc *r_rel)
{
  bfd_vma target_offset;
  unsigned long r_symndx;

  BFD_ASSERT (!r_reloc_is_const (r_rel));
  r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
  target_offset = get_elf_r_symndx_offset (r_rel->abfd, r_symndx);
  return (target_offset + r_rel->rela.r_addend);
}


static struct elf_link_hash_entry *
r_reloc_get_hash_entry (const r_reloc *r_rel)
{
  unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
  return get_elf_r_symndx_hash_entry (r_rel->abfd, r_symndx);
}


static asection *
r_reloc_get_section (const r_reloc *r_rel)
{
  unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info);
  return get_elf_r_symndx_section (r_rel->abfd, r_symndx);
}


static bfd_boolean
r_reloc_is_defined (const r_reloc *r_rel)
{
  asection *sec;
  if (r_rel == NULL)
    return FALSE;

  sec = r_reloc_get_section (r_rel);
  if (sec == bfd_abs_section_ptr
      || sec == bfd_com_section_ptr
      || sec == bfd_und_section_ptr)
    return FALSE;
  return TRUE;
}


static void
r_reloc_init (r_reloc *r_rel,
	      bfd *abfd,
	      Elf_Internal_Rela *irel,
	      bfd_byte *contents,
	      bfd_size_type content_length)
{
  int r_type;
  reloc_howto_type *howto;

  if (irel)
    {
      r_rel->rela = *irel;
      r_rel->abfd = abfd;
      r_rel->target_offset = r_reloc_get_target_offset (r_rel);
      r_rel->virtual_offset = 0;
      r_type = ELF32_R_TYPE (r_rel->rela.r_info);
      howto = &elf_howto_table[r_type];
      if (howto->partial_inplace)
	{
	  bfd_vma inplace_val;
	  BFD_ASSERT (r_rel->rela.r_offset < content_length);

	  inplace_val = bfd_get_32 (abfd, &contents[r_rel->rela.r_offset]);
	  r_rel->target_offset += inplace_val;
	}
    }
  else
    memset (r_rel, 0, sizeof (r_reloc));
}


#if DEBUG

static void
print_r_reloc (FILE *fp, const r_reloc *r_rel)
{
  if (r_reloc_is_defined (r_rel))
    {
      asection *sec = r_reloc_get_section (r_rel);
      fprintf (fp, " %s(%s + ", sec->owner->filename, sec->name);
    }
  else if (r_reloc_get_hash_entry (r_rel))
    fprintf (fp, " %s + ", r_reloc_get_hash_entry (r_rel)->root.root.string);
  else
    fprintf (fp, " ?? + ");

  fprintf_vma (fp, r_rel->target_offset);
  if (r_rel->virtual_offset)
    {
      fprintf (fp, " + ");
      fprintf_vma (fp, r_rel->virtual_offset);
    }
    
  fprintf (fp, ")");
}

#endif /* DEBUG */


/* source_reloc: relocations that reference literals.  */

/* To determine whether literals can be coalesced, we need to first
   record all the relocations that reference the literals.  The
   source_reloc structure below is used for this purpose.  The
   source_reloc entries are kept in a per-literal-section array, sorted
   by offset within the literal section (i.e., target offset).

   The source_sec and r_rel.rela.r_offset fields identify the source of
   the relocation.  The r_rel field records the relocation value, i.e.,
   the offset of the literal being referenced.  The opnd field is needed
   to determine the range of the immediate field to which the relocation
   applies, so we can determine whether another literal with the same
   value is within range.  The is_null field is true when the relocation
   is being removed (e.g., when an L32R is being removed due to a CALLX
   that is converted to a direct CALL).  */

typedef struct source_reloc_struct source_reloc;

struct source_reloc_struct
{
  asection *source_sec;
  r_reloc r_rel;
  xtensa_opcode opcode;
  int opnd;
  bfd_boolean is_null;
  bfd_boolean is_abs_literal;
};


static void
init_source_reloc (source_reloc *reloc,
		   asection *source_sec,
		   const r_reloc *r_rel,
		   xtensa_opcode opcode,
		   int opnd,
		   bfd_boolean is_abs_literal)
{
  reloc->source_sec = source_sec;
  reloc->r_rel = *r_rel;
  reloc->opcode = opcode;
  reloc->opnd = opnd;
  reloc->is_null = FALSE;
  reloc->is_abs_literal = is_abs_literal;
}


/* Find the source_reloc for a particular source offset and relocation
   type.  Note that the array is sorted by _target_ offset, so this is
   just a linear search.  */

static source_reloc *
find_source_reloc (source_reloc *src_relocs,
		   int src_count,
		   asection *sec,
		   Elf_Internal_Rela *irel)
{
  int i;

  for (i = 0; i < src_count; i++)
    {
      if (src_relocs[i].source_sec == sec
	  && src_relocs[i].r_rel.rela.r_offset == irel->r_offset
	  && (ELF32_R_TYPE (src_relocs[i].r_rel.rela.r_info)
	      == ELF32_R_TYPE (irel->r_info)))
	return &src_relocs[i];
    }

  return NULL;
}


static int
source_reloc_compare (const void *ap, const void *bp)
{
  const source_reloc *a = (const source_reloc *) ap;
  const source_reloc *b = (const source_reloc *) bp;

  if (a->r_rel.target_offset != b->r_rel.target_offset)
    return (a->r_rel.target_offset - b->r_rel.target_offset);

  /* We don't need to sort on these criteria for correctness,
     but enforcing a more strict ordering prevents unstable qsort
     from behaving differently with different implementations.
     Without the code below we get correct but different results
     on Solaris 2.7 and 2.8.  We would like to always produce the
     same results no matter the host. */

  if ((!a->is_null) - (!b->is_null))
    return ((!a->is_null) - (!b->is_null));
  return internal_reloc_compare (&a->r_rel.rela, &b->r_rel.rela);
}


/* Literal values and value hash tables.  */

/* Literals with the same value can be coalesced.  The literal_value
   structure records the value of a literal: the "r_rel" field holds the
   information from the relocation on the literal (if there is one) and
   the "value" field holds the contents of the literal word itself.

   The value_map structure records a literal value along with the
   location of a literal holding that value.  The value_map hash table
   is indexed by the literal value, so that we can quickly check if a
   particular literal value has been seen before and is thus a candidate
   for coalescing.  */

typedef struct literal_value_struct literal_value;
typedef struct value_map_struct value_map;
typedef struct value_map_hash_table_struct value_map_hash_table;

struct literal_value_struct
{
  r_reloc r_rel; 
  unsigned long value;
  bfd_boolean is_abs_literal;
};

struct value_map_struct
{
  literal_value val;			/* The literal value.  */
  r_reloc loc;				/* Location of the literal.  */
  value_map *next;
};

struct value_map_hash_table_struct
{
  unsigned bucket_count;
  value_map **buckets;
  unsigned count;
  bfd_boolean has_last_loc;
  r_reloc last_loc;
};


static void
init_literal_value (literal_value *lit,
		    const r_reloc *r_rel,
		    unsigned long value,
		    bfd_boolean is_abs_literal)
{
  lit->r_rel = *r_rel;
  lit->value = value;
  lit->is_abs_literal = is_abs_literal;
}


static bfd_boolean
literal_value_equal (const literal_value *src1,
		     const literal_value *src2,
		     bfd_boolean final_static_link)
{
  struct elf_link_hash_entry *h1, *h2;

  if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel)) 
    return FALSE;

  if (r_reloc_is_const (&src1->r_rel))
    return (src1->value == src2->value);

  if (ELF32_R_TYPE (src1->r_rel.rela.r_info)
      != ELF32_R_TYPE (src2->r_rel.rela.r_info))
    return FALSE;

  if (src1->r_rel.target_offset != src2->r_rel.target_offset)
    return FALSE;
   
  if (src1->r_rel.virtual_offset != src2->r_rel.virtual_offset)
    return FALSE;

  if (src1->value != src2->value)
    return FALSE;
  
  /* Now check for the same section (if defined) or the same elf_hash
     (if undefined or weak).  */
  h1 = r_reloc_get_hash_entry (&src1->r_rel);
  h2 = r_reloc_get_hash_entry (&src2->r_rel);
  if (r_reloc_is_defined (&src1->r_rel)
      && (final_static_link
	  || ((!h1 || h1->root.type != bfd_link_hash_defweak)
	      && (!h2 || h2->root.type != bfd_link_hash_defweak))))
    {
      if (r_reloc_get_section (&src1->r_rel)
	  != r_reloc_get_section (&src2->r_rel))
	return FALSE;
    }
  else
    {
      /* Require that the hash entries (i.e., symbols) be identical.  */
      if (h1 != h2 || h1 == 0)
	return FALSE;
    }

  if (src1->is_abs_literal != src2->is_abs_literal)
    return FALSE;

  return TRUE;
}


/* Must be power of 2.  */
#define INITIAL_HASH_RELOC_BUCKET_COUNT 1024

static value_map_hash_table *
value_map_hash_table_init (void)
{
  value_map_hash_table *values;

  values = (value_map_hash_table *)
    bfd_zmalloc (sizeof (value_map_hash_table));
  values->bucket_count = INITIAL_HASH_RELOC_BUCKET_COUNT;
  values->count = 0;
  values->buckets = (value_map **)
    bfd_zmalloc (sizeof (value_map *) * values->bucket_count);
  if (values->buckets == NULL) 
    {
      free (values);
      return NULL;
    }
  values->has_last_loc = FALSE;

  return values;
}


static void
value_map_hash_table_delete (value_map_hash_table *table)
{
  free (table->buckets);
  free (table);
}


static unsigned
hash_bfd_vma (bfd_vma val)
{
  return (val >> 2) + (val >> 10);
}


static unsigned
literal_value_hash (const literal_value *src)
{
  unsigned hash_val;

  hash_val = hash_bfd_vma (src->value);
  if (!r_reloc_is_const (&src->r_rel))
    {
      void *sec_or_hash;

      hash_val += hash_bfd_vma (src->is_abs_literal * 1000);
      hash_val += hash_bfd_vma (src->r_rel.target_offset);
      hash_val += hash_bfd_vma (src->r_rel.virtual_offset);
  
      /* Now check for the same section and the same elf_hash.  */
      if (r_reloc_is_defined (&src->r_rel))
	sec_or_hash = r_reloc_get_section (&src->r_rel);
      else
	sec_or_hash = r_reloc_get_hash_entry (&src->r_rel);
      hash_val += hash_bfd_vma ((bfd_vma) (unsigned) sec_or_hash);
    }
  return hash_val;
}


/* Check if the specified literal_value has been seen before.  */

static value_map *
value_map_get_cached_value (value_map_hash_table *map,
			    const literal_value *val,
			    bfd_boolean final_static_link)
{
  value_map *map_e;
  value_map *bucket;
  unsigned idx;

  idx = literal_value_hash (val);
  idx = idx & (map->bucket_count - 1);
  bucket = map->buckets[idx];
  for (map_e = bucket; map_e; map_e = map_e->next)
    {
      if (literal_value_equal (&map_e->val, val, final_static_link))
	return map_e;
    }
  return NULL;
}


/* Record a new literal value.  It is illegal to call this if VALUE
   already has an entry here.  */

static value_map *
add_value_map (value_map_hash_table *map,
	       const literal_value *val,
	       const r_reloc *loc,
	       bfd_boolean final_static_link)
{
  value_map **bucket_p;
  unsigned idx;

  value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map));
  if (val_e == NULL)
    {
      bfd_set_error (bfd_error_no_memory);
      return NULL;
    }

  BFD_ASSERT (!value_map_get_cached_value (map, val, final_static_link));
  val_e->val = *val;
  val_e->loc = *loc;

  idx = literal_value_hash (val);
  idx = idx & (map->bucket_count - 1);
  bucket_p = &map->buckets[idx];

  val_e->next = *bucket_p;
  *bucket_p = val_e;
  map->count++;
  /* FIXME: Consider resizing the hash table if we get too many entries.  */
  
  return val_e;
}


/* Lists of text actions (ta_) for narrowing, widening, longcall
   conversion, space fill, code & literal removal, etc.  */

/* The following text actions are generated:

   "ta_remove_insn"         remove an instruction or instructions
   "ta_remove_longcall"     convert longcall to call
   "ta_convert_longcall"    convert longcall to nop/call
   "ta_narrow_insn"         narrow a wide instruction
   "ta_widen"               widen a narrow instruction
   "ta_fill"                add fill or remove fill
      removed < 0 is a fill; branches to the fill address will be
	changed to address + fill size (e.g., address - removed)
      removed >= 0 branches to the fill address will stay unchanged
   "ta_remove_literal"      remove a literal; this action is
			    indicated when a literal is removed
                            or replaced.
   "ta_add_literal"         insert a new literal; this action is
                            indicated when a literal has been moved.
                            It may use a virtual_offset because
			    multiple literals can be placed at the
                            same location.

   For each of these text actions, we also record the number of bytes
   removed by performing the text action.  In the case of a "ta_widen"
   or a "ta_fill" that adds space, the removed_bytes will be negative.  */

typedef struct text_action_struct text_action;
typedef struct text_action_list_struct text_action_list;
typedef enum text_action_enum_t text_action_t;

enum text_action_enum_t
{
  ta_none,
  ta_remove_insn,        /* removed = -size */
  ta_remove_longcall,    /* removed = -size */
  ta_convert_longcall,   /* removed = 0 */
  ta_narrow_insn,        /* removed = -1 */
  ta_widen_insn,         /* removed = +1 */
  ta_fill,               /* removed = +size */
  ta_remove_literal,
  ta_add_literal
};


/* Structure for a text action record.  */
struct text_action_struct
{
  text_action_t action;
  asection *sec;	/* Optional */
  bfd_vma offset;
  bfd_vma virtual_offset;  /* Zero except for adding literals.  */
  int removed_bytes;
  literal_value value;	/* Only valid when adding literals.  */

  text_action *next;
};


/* List of all of the actions taken on a text section.  */
struct text_action_list_struct
{
  text_action *head;
};


static text_action *
find_fill_action (text_action_list *l, asection *sec, bfd_vma offset)
{
  text_action **m_p;

  /* It is not necessary to fill at the end of a section.  */
  if (sec->size == offset)
    return NULL;

  for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next)
    {
      text_action *t = *m_p;
      /* When the action is another fill at the same address,
	 just increase the size.  */
      if (t->offset == offset && t->action == ta_fill)
	return t;
    }
  return NULL;
}


static int
compute_removed_action_diff (const text_action *ta,
			     asection *sec,
			     bfd_vma offset,
			     int removed,
			     int removable_space)
{
  int new_removed;
  int current_removed = 0;

  if (ta)
    current_removed = ta->removed_bytes;

  BFD_ASSERT (ta == NULL || ta->offset == offset);
  BFD_ASSERT (ta == NULL || ta->action == ta_fill);

  /* It is not necessary to fill at the end of a section.  Clean this up.  */
  if (sec->size == offset)
    new_removed = removable_space - 0;
  else
    {
      int space;
      int added = -removed - current_removed;
      /* Ignore multiples of the section alignment.  */
      added = ((1 << sec->alignment_power) - 1) & added;
      new_removed = (-added);

      /* Modify for removable.  */
      space = removable_space - new_removed;
      new_removed = (removable_space
		     - (((1 << sec->alignment_power) - 1) & space));
    }
  return (new_removed - current_removed);
}


static void
adjust_fill_action (text_action *ta, int fill_diff)
{
  ta->removed_bytes += fill_diff;
}


/* Add a modification action to the text.  For the case of adding or
   removing space, modify any current fill and assume that
   "unreachable_space" bytes can be freely contracted.  Note that a
   negative removed value is a fill.  */

static void 
text_action_add (text_action_list *l,
		 text_action_t action,
		 asection *sec,
		 bfd_vma offset,
		 int removed)
{
  text_action **m_p;
  text_action *ta;

  /* It is not necessary to fill at the end of a section.  */
  if (action == ta_fill && sec->size == offset)
    return;

  /* It is not necessary to fill 0 bytes.  */
  if (action == ta_fill && removed == 0)
    return;

  for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next)
    {
      text_action *t = *m_p;
      /* When the action is another fill at the same address,
	 just increase the size.  */
      if (t->offset == offset && t->action == ta_fill && action == ta_fill)
	{
	  t->removed_bytes += removed;
	  return;
	}
    }

  /* Create a new record and fill it up.  */
  ta = (text_action *) bfd_zmalloc (sizeof (text_action));
  ta->action = action;
  ta->sec = sec;
  ta->offset = offset;
  ta->removed_bytes = removed;
  ta->next = (*m_p);
  *m_p = ta;
}


static void
text_action_add_literal (text_action_list *l,
			 text_action_t action,
			 const r_reloc *loc,
			 const literal_value *value,
			 int removed)
{
  text_action **m_p;
  text_action *ta;
  asection *sec = r_reloc_get_section (loc);
  bfd_vma offset = loc->target_offset;
  bfd_vma virtual_offset = loc->virtual_offset;

  BFD_ASSERT (action == ta_add_literal);

  for (m_p = &l->head; *m_p != NULL; m_p = &(*m_p)->next)
    {
      if ((*m_p)->offset > offset
	  && ((*m_p)->offset != offset
	      || (*m_p)->virtual_offset > virtual_offset))
	break;
    }

  /* Create a new record and fill it up.  */
  ta = (text_action *) bfd_zmalloc (sizeof (text_action));
  ta->action = action;
  ta->sec = sec;
  ta->offset = offset;
  ta->virtual_offset = virtual_offset;
  ta->value = *value;
  ta->removed_bytes = removed;
  ta->next = (*m_p);
  *m_p = ta;
}


static bfd_vma 
offset_with_removed_text (text_action_list *action_list, bfd_vma offset)
{
  text_action *r;
  int removed = 0;

  for (r = action_list->head; r && r->offset <= offset; r = r->next)
    {
      if (r->offset < offset
	  || (r->action == ta_fill && r->removed_bytes < 0))
	removed += r->removed_bytes;
    }

  return (offset - removed);
}


static bfd_vma
offset_with_removed_text_before_fill (text_action_list *action_list,
				      bfd_vma offset)
{
  text_action *r;
  int removed = 0;

  for (r = action_list->head; r && r->offset < offset; r = r->next)
    removed += r->removed_bytes;

  return (offset - removed);
}


/* The find_insn_action routine will only find non-fill actions.  */

static text_action *
find_insn_action (text_action_list *action_list, bfd_vma offset)
{
  text_action *t;
  for (t = action_list->head; t; t = t->next)
    {
      if (t->offset == offset)
	{
	  switch (t->action)
	    {
	    case ta_none:
	    case ta_fill:
	      break;
	    case ta_remove_insn:
	    case ta_remove_longcall:
	    case ta_convert_longcall:
	    case ta_narrow_insn:
	    case ta_widen_insn:
	      return t;
	    case ta_remove_literal:
	    case ta_add_literal:
	      BFD_ASSERT (0);
	      break;
	    }
	}
    }
  return NULL;
}


#if DEBUG

static void
print_action_list (FILE *fp, text_action_list *action_list)
{
  text_action *r;

  fprintf (fp, "Text Action\n");
  for (r = action_list->head; r != NULL; r = r->next)
    {
      const char *t = "unknown";
      switch (r->action)
	{
	case ta_remove_insn:
	  t = "remove_insn"; break;
	case ta_remove_longcall:
	  t = "remove_longcall"; break;
	case ta_convert_longcall:
	  t = "remove_longcall"; break;
	case ta_narrow_insn:
	  t = "narrow_insn"; break;
	case ta_widen_insn:
	  t = "widen_insn"; break;
	case ta_fill:
	  t = "fill"; break;
	case ta_none:
	  t = "none"; break;
	case ta_remove_literal:
	  t = "remove_literal"; break;
	case ta_add_literal:
	  t = "add_literal"; break;
	}

      fprintf (fp, "%s: %s[0x%lx] \"%s\" %d\n",
	       r->sec->owner->filename,
	       r->sec->name, r->offset, t, r->removed_bytes);
    }
}

#endif /* DEBUG */


/* Lists of literals being coalesced or removed.  */

/* In the usual case, the literal identified by "from" is being
   coalesced with another literal identified by "to".  If the literal is
   unused and is being removed altogether, "to.abfd" will be NULL.
   The removed_literal entries are kept on a per-section list, sorted
   by the "from" offset field.  */

typedef struct removed_literal_struct removed_literal;
typedef struct removed_literal_list_struct removed_literal_list;

struct removed_literal_struct
{
  r_reloc from;
  r_reloc to;
  removed_literal *next;
};

struct removed_literal_list_struct
{
  removed_literal *head;
  removed_literal *tail;
};


/* Record that the literal at "from" is being removed.  If "to" is not
   NULL, the "from" literal is being coalesced with the "to" literal.  */

static void
add_removed_literal (removed_literal_list *removed_list,
		     const r_reloc *from,
		     const r_reloc *to)
{
  removed_literal *r, *new_r, *next_r;

  new_r = (removed_literal *) bfd_zmalloc (sizeof (removed_literal));

  new_r->from = *from;
  if (to)
    new_r->to = *to;
  else
    new_r->to.abfd = NULL;
  new_r->next = NULL;
  
  r = removed_list->head;
  if (r == NULL) 
    {
      removed_list->head = new_r;
      removed_list->tail = new_r;
    }
  /* Special check for common case of append.  */
  else if (removed_list->tail->from.target_offset < from->target_offset)
    {
      removed_list->tail->next = new_r;
      removed_list->tail = new_r;
    }
  else
    {
      while (r->from.target_offset < from->target_offset && r->next) 
	{
	  r = r->next;
	}
      next_r = r->next;
      r->next = new_r;
      new_r->next = next_r;
      if (next_r == NULL)
	removed_list->tail = new_r;
    }
}


/* Check if the list of removed literals contains an entry for the
   given address.  Return the entry if found.  */

static removed_literal *
find_removed_literal (removed_literal_list *removed_list, bfd_vma addr)
{
  removed_literal *r = removed_list->head;
  while (r && r->from.target_offset < addr)
    r = r->next;
  if (r && r->from.target_offset == addr)
    return r;
  return NULL;
}


#if DEBUG

static void
print_removed_literals (FILE *fp, removed_literal_list *removed_list)
{
  removed_literal *r;
  r = removed_list->head;
  if (r)
    fprintf (fp, "Removed Literals\n");
  for (; r != NULL; r = r->next)
    {
      print_r_reloc (fp, &r->from);
      fprintf (fp, " => ");
      if (r->to.abfd == NULL)
	fprintf (fp, "REMOVED");
      else
	print_r_reloc (fp, &r->to);
      fprintf (fp, "\n");
    }
}

#endif /* DEBUG */


/* Per-section data for relaxation.  */

typedef struct reloc_bfd_fix_struct reloc_bfd_fix;

struct xtensa_relax_info_struct
{
  bfd_boolean is_relaxable_literal_section;
  bfd_boolean is_relaxable_asm_section;
  int visited;				/* Number of times visited.  */

  source_reloc *src_relocs;		/* Array[src_count].  */
  int src_count;
  int src_next;				/* Next src_relocs entry to assign.  */

  removed_literal_list removed_list;
  text_action_list action_list;

  reloc_bfd_fix *fix_list;
  reloc_bfd_fix *fix_array;
  unsigned fix_array_count;

  /* Support for expanding the reloc array that is stored
     in the section structure.  If the relocations have been
     reallocated, the newly allocated relocations will be referenced
     here along with the actual size allocated.  The relocation
     count will always be found in the section structure.  */
  Elf_Internal_Rela *allocated_relocs; 
  unsigned relocs_count;
  unsigned allocated_relocs_count;
};

struct elf_xtensa_section_data
{
  struct bfd_elf_section_data elf;
  xtensa_relax_info relax_info;
};


static bfd_boolean
elf_xtensa_new_section_hook (bfd *abfd, asection *sec)
{
  struct elf_xtensa_section_data *sdata;
  bfd_size_type amt = sizeof (*sdata);

  sdata = (struct elf_xtensa_section_data *) bfd_zalloc (abfd, amt);
  if (sdata == NULL)
    return FALSE;
  sec->used_by_bfd = (void *) sdata;

  return _bfd_elf_new_section_hook (abfd, sec);
}


static xtensa_relax_info *
get_xtensa_relax_info (asection *sec)
{
  struct elf_xtensa_section_data *section_data;

  /* No info available if no section or if it is an output section.  */
  if (!sec || sec == sec->output_section)
    return NULL;

  section_data = (struct elf_xtensa_section_data *) elf_section_data (sec);
  return &section_data->relax_info;
}


static void
init_xtensa_relax_info (asection *sec)
{
  xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);

  relax_info->is_relaxable_literal_section = FALSE;
  relax_info->is_relaxable_asm_section = FALSE;
  relax_info->visited = 0;

  relax_info->src_relocs = NULL;
  relax_info->src_count = 0;
  relax_info->src_next = 0;

  relax_info->removed_list.head = NULL;
  relax_info->removed_list.tail = NULL;

  relax_info->action_list.head = NULL;

  relax_info->fix_list = NULL;
  relax_info->fix_array = NULL;
  relax_info->fix_array_count = 0;

  relax_info->allocated_relocs = NULL; 
  relax_info->relocs_count = 0;
  relax_info->allocated_relocs_count = 0;
}


/* Coalescing literals may require a relocation to refer to a section in
   a different input file, but the standard relocation information
   cannot express that.  Instead, the reloc_bfd_fix structures are used
   to "fix" the relocations that refer to sections in other input files.
   These structures are kept on per-section lists.  The "src_type" field
   records the relocation type in case there are multiple relocations on
   the same location.  FIXME: This is ugly; an alternative might be to
   add new symbols with the "owner" field to some other input file.  */

struct reloc_bfd_fix_struct
{
  asection *src_sec;
  bfd_vma src_offset;
  unsigned src_type;			/* Relocation type.  */
  
  bfd *target_abfd;
  asection *target_sec;
  bfd_vma target_offset;
  bfd_boolean translated;
  
  reloc_bfd_fix *next;
};


static reloc_bfd_fix *
reloc_bfd_fix_init (asection *src_sec,
		    bfd_vma src_offset,
		    unsigned src_type,
		    bfd *target_abfd,
		    asection *target_sec,
		    bfd_vma target_offset,
		    bfd_boolean translated)
{
  reloc_bfd_fix *fix;

  fix = (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix));
  fix->src_sec = src_sec;
  fix->src_offset = src_offset;
  fix->src_type = src_type;
  fix->target_abfd = target_abfd;
  fix->target_sec = target_sec;
  fix->target_offset = target_offset;
  fix->translated = translated;

  return fix;
}


static void
add_fix (asection *src_sec, reloc_bfd_fix *fix)
{
  xtensa_relax_info *relax_info;

  relax_info = get_xtensa_relax_info (src_sec);
  fix->next = relax_info->fix_list;
  relax_info->fix_list = fix;
}


static int
fix_compare (const void *ap, const void *bp)
{
  const reloc_bfd_fix *a = (const reloc_bfd_fix *) ap;
  const reloc_bfd_fix *b = (const reloc_bfd_fix *) bp;

  if (a->src_offset != b->src_offset)
    return (a->src_offset - b->src_offset);
  return (a->src_type - b->src_type);
}


static void
cache_fix_array (asection *sec)
{
  unsigned i, count = 0;
  reloc_bfd_fix *r;
  xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);

  if (relax_info == NULL)
    return;
  if (relax_info->fix_list == NULL)
    return;

  for (r = relax_info->fix_list; r != NULL; r = r->next)
    count++;

  relax_info->fix_array =
    (reloc_bfd_fix *) bfd_malloc (sizeof (reloc_bfd_fix) * count);
  relax_info->fix_array_count = count;

  r = relax_info->fix_list;
  for (i = 0; i < count; i++, r = r->next)
    {
      relax_info->fix_array[count - 1 - i] = *r;
      relax_info->fix_array[count - 1 - i].next = NULL;
    }

  qsort (relax_info->fix_array, relax_info->fix_array_count,
	 sizeof (reloc_bfd_fix), fix_compare);
}


static reloc_bfd_fix *
get_bfd_fix (asection *sec, bfd_vma offset, unsigned type)
{
  xtensa_relax_info *relax_info = get_xtensa_relax_info (sec);
  reloc_bfd_fix *rv;
  reloc_bfd_fix key;

  if (relax_info == NULL)
    return NULL;
  if (relax_info->fix_list == NULL)
    return NULL;

  if (relax_info->fix_array == NULL)
    cache_fix_array (sec);

  key.src_offset = offset;
  key.src_type = type;
  rv = bsearch (&key, relax_info->fix_array,  relax_info->fix_array_count,
		sizeof (reloc_bfd_fix), fix_compare);
  return rv;
}


/* Section caching.  */

typedef struct section_cache_struct section_cache_t;

struct section_cache_struct
{
  asection *sec;

  bfd_byte *contents;		/* Cache of the section contents.  */
  bfd_size_type content_length;

  property_table_entry *ptbl;	/* Cache of the section property table.  */
  unsigned pte_count;

  Elf_Internal_Rela *relocs;	/* Cache of the section relocations.  */
  unsigned reloc_count;
};


static void
init_section_cache (section_cache_t *sec_cache)
{
  memset (sec_cache, 0, sizeof (*sec_cache));
}


static void
clear_section_cache (section_cache_t *sec_cache)
{
  if (sec_cache->sec)
    {
      release_contents (sec_cache->sec, sec_cache->contents);
      release_internal_relocs (sec_cache->sec, sec_cache->relocs);
      if (sec_cache->ptbl)
	free (sec_cache->ptbl);
      memset (sec_cache, 0, sizeof (sec_cache));
    }
}


static bfd_boolean
section_cache_section (section_cache_t *sec_cache,
		       asection *sec,
		       struct bfd_link_info *link_info)
{
  bfd *abfd;
  property_table_entry *prop_table = NULL;
  int ptblsize = 0;
  bfd_byte *contents = NULL;
  Elf_Internal_Rela *internal_relocs = NULL;
  bfd_size_type sec_size;

  if (sec == NULL)
    return FALSE;
  if (sec == sec_cache->sec)
    return TRUE;

  abfd = sec->owner;
  sec_size = bfd_get_section_limit (abfd, sec);

  /* Get the contents.  */
  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec_size != 0)
    goto err;

  /* Get the relocations.  */
  internal_relocs = retrieve_internal_relocs (abfd, sec,
					      link_info->keep_memory);

  /* Get the entry table.  */
  ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
					XTENSA_PROP_SEC_NAME, FALSE);
  if (ptblsize < 0)
    goto err;

  /* Fill in the new section cache.  */
  clear_section_cache (sec_cache);
  memset (sec_cache, 0, sizeof (sec_cache));

  sec_cache->sec = sec;
  sec_cache->contents = contents;
  sec_cache->content_length = sec_size;
  sec_cache->relocs = internal_relocs;
  sec_cache->reloc_count = sec->reloc_count;
  sec_cache->pte_count = ptblsize;
  sec_cache->ptbl = prop_table;

  return TRUE;

 err:
  release_contents (sec, contents);
  release_internal_relocs (sec, internal_relocs);
  if (prop_table)
    free (prop_table);
  return FALSE;
}


/* Extended basic blocks.  */

/* An ebb_struct represents an Extended Basic Block.  Within this
   range, we guarantee that all instructions are decodable, the
   property table entries are contiguous, and no property table
   specifies a segment that cannot have instructions moved.  This
   structure contains caches of the contents, property table and
   relocations for the specified section for easy use.  The range is
   specified by ranges of indices for the byte offset, property table
   offsets and relocation offsets.  These must be consistent.  */

typedef struct ebb_struct ebb_t;

struct ebb_struct
{
  asection *sec;

  bfd_byte *contents;		/* Cache of the section contents.  */
  bfd_size_type content_length;

  property_table_entry *ptbl;	/* Cache of the section property table.  */
  unsigned pte_count;

  Elf_Internal_Rela *relocs;	/* Cache of the section relocations.  */
  unsigned reloc_count;

  bfd_vma start_offset;		/* Offset in section.  */
  unsigned start_ptbl_idx;	/* Offset in the property table.  */
  unsigned start_reloc_idx;	/* Offset in the relocations.  */

  bfd_vma end_offset;
  unsigned end_ptbl_idx;
  unsigned end_reloc_idx;

  bfd_boolean ends_section;	/* Is this the last ebb in a section?  */

  /* The unreachable property table at the end of this set of blocks;
     NULL if the end is not an unreachable block.  */
  property_table_entry *ends_unreachable;
};


enum ebb_target_enum
{
  EBB_NO_ALIGN = 0,
  EBB_DESIRE_TGT_ALIGN,
  EBB_REQUIRE_TGT_ALIGN,
  EBB_REQUIRE_LOOP_ALIGN,
  EBB_REQUIRE_ALIGN
};


/* proposed_action_struct is similar to the text_action_struct except
   that is represents a potential transformation, not one that will
   occur.  We build a list of these for an extended basic block
   and use them to compute the actual actions desired.  We must be
   careful that the entire set of actual actions we perform do not
   break any relocations that would fit if the actions were not
   performed.  */

typedef struct proposed_action_struct proposed_action;

struct proposed_action_struct
{
  enum ebb_target_enum align_type; /* for the target alignment */
  bfd_vma alignment_pow;
  text_action_t action;
  bfd_vma offset;
  int removed_bytes;
  bfd_boolean do_action; /* If false, then we will not perform the action.  */
};


/* The ebb_constraint_struct keeps a set of proposed actions for an
   extended basic block.   */

typedef struct ebb_constraint_struct ebb_constraint;

struct ebb_constraint_struct
{
  ebb_t ebb;
  bfd_boolean start_movable;

  /* Bytes of extra space at the beginning if movable.  */
  int start_extra_space;

  enum ebb_target_enum start_align;

  bfd_boolean end_movable;

  /* Bytes of extra space at the end if movable.  */
  int end_extra_space;

  unsigned action_count;
  unsigned action_allocated;

  /* Array of proposed actions.  */
  proposed_action *actions;

  /* Action alignments -- one for each proposed action.  */
  enum ebb_target_enum *action_aligns;
};


static void
init_ebb_constraint (ebb_constraint *c)
{
  memset (c, 0, sizeof (ebb_constraint));
}


static void
free_ebb_constraint (ebb_constraint *c)
{
  if (c->actions)
    free (c->actions);
}


static void
init_ebb (ebb_t *ebb,
	  asection *sec,
	  bfd_byte *contents,
	  bfd_size_type content_length,
	  property_table_entry *prop_table,
	  unsigned ptblsize,
	  Elf_Internal_Rela *internal_relocs,
	  unsigned reloc_count)
{
  memset (ebb, 0, sizeof (ebb_t));
  ebb->sec = sec;
  ebb->contents = contents;
  ebb->content_length = content_length;
  ebb->ptbl = prop_table;
  ebb->pte_count = ptblsize;
  ebb->relocs = internal_relocs;
  ebb->reloc_count = reloc_count;
  ebb->start_offset = 0;
  ebb->end_offset = ebb->content_length - 1;
  ebb->start_ptbl_idx = 0;
  ebb->end_ptbl_idx = ptblsize;
  ebb->start_reloc_idx = 0;
  ebb->end_reloc_idx = reloc_count;
}


/* Extend the ebb to all decodable contiguous sections.  The algorithm
   for building a basic block around an instruction is to push it
   forward until we hit the end of a section, an unreachable block or
   a block that cannot be transformed.  Then we push it backwards
   searching for similar conditions.  */

static bfd_boolean extend_ebb_bounds_forward (ebb_t *);
static bfd_boolean extend_ebb_bounds_backward (ebb_t *);
static bfd_size_type insn_block_decodable_len
  (bfd_byte *, bfd_size_type, bfd_vma, bfd_size_type);

static bfd_boolean
extend_ebb_bounds (ebb_t *ebb)
{
  if (!extend_ebb_bounds_forward (ebb))
    return FALSE;
  if (!extend_ebb_bounds_backward (ebb))
    return FALSE;
  return TRUE;
}


static bfd_boolean
extend_ebb_bounds_forward (ebb_t *ebb)
{
  property_table_entry *the_entry, *new_entry;

  the_entry = &ebb->ptbl[ebb->end_ptbl_idx];

  /* Stop when (1) we cannot decode an instruction, (2) we are at
     the end of the property tables, (3) we hit a non-contiguous property
     table entry, (4) we hit a NO_TRANSFORM region.  */

  while (1)
    {
      bfd_vma entry_end;
      bfd_size_type insn_block_len;

      entry_end = the_entry->address - ebb->sec->vma + the_entry->size;
      insn_block_len =
	insn_block_decodable_len (ebb->contents, ebb->content_length,
				  ebb->end_offset,
				  entry_end - ebb->end_offset);
      if (insn_block_len != (entry_end - ebb->end_offset))
	{
	  (*_bfd_error_handler)
	    (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
	     ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
	  return FALSE;
	}
      ebb->end_offset += insn_block_len;

      if (ebb->end_offset == ebb->sec->size)
	ebb->ends_section = TRUE;

      /* Update the reloc counter.  */
      while (ebb->end_reloc_idx + 1 < ebb->reloc_count
	     && (ebb->relocs[ebb->end_reloc_idx + 1].r_offset
		 < ebb->end_offset))
	{
	  ebb->end_reloc_idx++;
	}

      if (ebb->end_ptbl_idx + 1 == ebb->pte_count)
	return TRUE;

      new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1];
      if (((new_entry->flags & XTENSA_PROP_INSN) == 0)
	  || ((new_entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) != 0)
	  || ((the_entry->flags & XTENSA_PROP_ALIGN) != 0))
	break;

      if (the_entry->address + the_entry->size != new_entry->address)
	break;

      the_entry = new_entry;
      ebb->end_ptbl_idx++;
    }

  /* Quick check for an unreachable or end of file just at the end.  */
  if (ebb->end_ptbl_idx + 1 == ebb->pte_count)
    {
      if (ebb->end_offset == ebb->content_length)
	ebb->ends_section = TRUE;
    }
  else
    {
      new_entry = &ebb->ptbl[ebb->end_ptbl_idx + 1];
      if ((new_entry->flags & XTENSA_PROP_UNREACHABLE) != 0
	  && the_entry->address + the_entry->size == new_entry->address)
	ebb->ends_unreachable = new_entry;
    }

  /* Any other ending requires exact alignment.  */
  return TRUE;
}


static bfd_boolean
extend_ebb_bounds_backward (ebb_t *ebb)
{
  property_table_entry *the_entry, *new_entry;

  the_entry = &ebb->ptbl[ebb->start_ptbl_idx];

  /* Stop when (1) we cannot decode the instructions in the current entry.
     (2) we are at the beginning of the property tables, (3) we hit a
     non-contiguous property table entry, (4) we hit a NO_TRANSFORM region.  */

  while (1)
    {
      bfd_vma block_begin;
      bfd_size_type insn_block_len;

      block_begin = the_entry->address - ebb->sec->vma;
      insn_block_len =
	insn_block_decodable_len (ebb->contents, ebb->content_length,
				  block_begin,
				  ebb->start_offset - block_begin);
      if (insn_block_len != ebb->start_offset - block_begin)
	{
	  (*_bfd_error_handler)
	    (_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
	     ebb->sec->owner, ebb->sec, ebb->end_offset + insn_block_len);
	  return FALSE;
	}
      ebb->start_offset -= insn_block_len;

      /* Update the reloc counter.  */
      while (ebb->start_reloc_idx > 0
	     && (ebb->relocs[ebb->start_reloc_idx - 1].r_offset
		 >= ebb->start_offset))
	{
	  ebb->start_reloc_idx--;
	}

      if (ebb->start_ptbl_idx == 0)
	return TRUE;

      new_entry = &ebb->ptbl[ebb->start_ptbl_idx - 1];
      if ((new_entry->flags & XTENSA_PROP_INSN) == 0
	  || ((new_entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) != 0)
	  || ((new_entry->flags & XTENSA_PROP_ALIGN) != 0))
	return TRUE;
      if (new_entry->address + new_entry->size != the_entry->address)
	return TRUE;

      the_entry = new_entry;
      ebb->start_ptbl_idx--;
    }
  return TRUE;
}


static bfd_size_type
insn_block_decodable_len (bfd_byte *contents,
			  bfd_size_type content_len,
			  bfd_vma block_offset,
			  bfd_size_type block_len)
{
  bfd_vma offset = block_offset;

  while (offset < block_offset + block_len)
    {
      bfd_size_type insn_len = 0;

      insn_len = insn_decode_len (contents, content_len, offset);
      if (insn_len == 0)
	return (offset - block_offset);
      offset += insn_len;
    }
  return (offset - block_offset);
}


static void
ebb_propose_action (ebb_constraint *c,
		    bfd_vma alignment_pow,
		    enum ebb_target_enum align_type,
		    text_action_t action,
		    bfd_vma offset,
		    int removed_bytes,
		    bfd_boolean do_action)
{
  proposed_action *act;

  if (c->action_allocated <= c->action_count)
    {
      unsigned new_allocated, i;

      new_allocated = (c->action_count + 2) * 2;
      proposed_action *new_actions = (proposed_action *)
	bfd_zmalloc (sizeof (proposed_action) * new_allocated);

      for (i = 0; i < c->action_count; i++)
	new_actions[i] = c->actions[i];
      if (c->actions)
	free (c->actions);
      c->actions = new_actions;
      c->action_allocated = new_allocated;
    }

  act = &c->actions[c->action_count];
  act->align_type = align_type;
  act->alignment_pow = alignment_pow;
  act->action = action;
  act->offset = offset;
  act->removed_bytes = removed_bytes;
  act->do_action = do_action;

  c->action_count++;
}


/* Access to internal relocations, section contents and symbols.  */

/* During relaxation, we need to modify relocations, section contents,
   and symbol definitions, and we need to keep the original values from
   being reloaded from the input files, i.e., we need to "pin" the
   modified values in memory.  We also want to continue to observe the
   setting of the "keep-memory" flag.  The following functions wrap the
   standard BFD functions to take care of this for us.  */

static Elf_Internal_Rela *
retrieve_internal_relocs (bfd *abfd, asection *sec, bfd_boolean keep_memory)
{
  Elf_Internal_Rela *internal_relocs;

  if ((sec->flags & SEC_LINKER_CREATED) != 0)
    return NULL;

  internal_relocs = elf_section_data (sec)->relocs;
  if (internal_relocs == NULL)
    internal_relocs = (_bfd_elf_link_read_relocs
		       (abfd, sec, NULL, NULL, keep_memory));
  return internal_relocs;
}


static void
pin_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs)
{
  elf_section_data (sec)->relocs = internal_relocs;
}


static void
release_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs)
{
  if (internal_relocs
      && elf_section_data (sec)->relocs != internal_relocs)
    free (internal_relocs);
}


static bfd_byte *
retrieve_contents (bfd *abfd, asection *sec, bfd_boolean keep_memory)
{
  bfd_byte *contents;
  bfd_size_type sec_size;

  sec_size = bfd_get_section_limit (abfd, sec);
  contents = elf_section_data (sec)->this_hdr.contents;
  
  if (contents == NULL && sec_size != 0)
    {
      if (!bfd_malloc_and_get_section (abfd, sec, &contents))
	{
	  if (contents)
	    free (contents);
	  return NULL;
	}
      if (keep_memory) 
	elf_section_data (sec)->this_hdr.contents = contents;
    }
  return contents;
}


static void
pin_contents (asection *sec, bfd_byte *contents)
{
  elf_section_data (sec)->this_hdr.contents = contents;
}


static void
release_contents (asection *sec, bfd_byte *contents)
{
  if (contents && elf_section_data (sec)->this_hdr.contents != contents)
    free (contents);
}


static Elf_Internal_Sym *
retrieve_local_syms (bfd *input_bfd)
{
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Sym *isymbuf;
  size_t locsymcount;

  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  locsymcount = symtab_hdr->sh_info;

  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
  if (isymbuf == NULL && locsymcount != 0)
    isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0,
				    NULL, NULL, NULL);

  /* Save the symbols for this input file so they won't be read again.  */
  if (isymbuf && isymbuf != (Elf_Internal_Sym *) symtab_hdr->contents)
    symtab_hdr->contents = (unsigned char *) isymbuf;

  return isymbuf;
}


/* Code for link-time relaxation.  */

/* Initialization for relaxation: */
static bfd_boolean analyze_relocations (struct bfd_link_info *);
static bfd_boolean find_relaxable_sections
  (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
static bfd_boolean collect_source_relocs
  (bfd *, asection *, struct bfd_link_info *);
static bfd_boolean is_resolvable_asm_expansion
  (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, struct bfd_link_info *,
   bfd_boolean *);
static Elf_Internal_Rela *find_associated_l32r_irel
  (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Rela *);
static bfd_boolean compute_text_actions
  (bfd *, asection *, struct bfd_link_info *);
static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *);
static bfd_boolean compute_ebb_actions (ebb_constraint *);
static bfd_boolean check_section_ebb_pcrels_fit
  (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, const ebb_constraint *);
static bfd_boolean check_section_ebb_reduces (const ebb_constraint *);
static void text_action_add_proposed
  (text_action_list *, const ebb_constraint *, asection *);
static int compute_fill_extra_space (property_table_entry *);

/* First pass: */
static bfd_boolean compute_removed_literals
  (bfd *, asection *, struct bfd_link_info *, value_map_hash_table *);
static Elf_Internal_Rela *get_irel_at_offset
  (asection *, Elf_Internal_Rela *, bfd_vma);
static bfd_boolean is_removable_literal 
  (const source_reloc *, int, const source_reloc *, int);
static bfd_boolean remove_dead_literal
  (bfd *, asection *, struct bfd_link_info *, Elf_Internal_Rela *,
   Elf_Internal_Rela *, source_reloc *, property_table_entry *, int); 
static bfd_boolean identify_literal_placement
  (bfd *, asection *, bfd_byte *, struct bfd_link_info *,
   value_map_hash_table *, bfd_boolean *, Elf_Internal_Rela *, int,
   source_reloc *, property_table_entry *, int, section_cache_t *,
   bfd_boolean);
static bfd_boolean relocations_reach (source_reloc *, int, const r_reloc *);
static bfd_boolean coalesce_shared_literal
  (asection *, source_reloc *, property_table_entry *, int, value_map *);
static bfd_boolean move_shared_literal
  (asection *, struct bfd_link_info *, source_reloc *, property_table_entry *,
   int, const r_reloc *, const literal_value *, section_cache_t *);

/* Second pass: */
static bfd_boolean relax_section (bfd *, asection *, struct bfd_link_info *);
static bfd_boolean translate_section_fixes (asection *);
static bfd_boolean translate_reloc_bfd_fix (reloc_bfd_fix *);
static void translate_reloc (const r_reloc *, r_reloc *);
static void shrink_dynamic_reloc_sections
  (struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *);
static bfd_boolean move_literal
  (bfd *, struct bfd_link_info *, asection *, bfd_vma, bfd_byte *,
   xtensa_relax_info *, Elf_Internal_Rela **, const literal_value *);
static bfd_boolean relax_property_section
  (bfd *, asection *, struct bfd_link_info *);

/* Third pass: */
static bfd_boolean relax_section_symbols (bfd *, asection *);


static bfd_boolean 
elf_xtensa_relax_section (bfd *abfd,
			  asection *sec,
			  struct bfd_link_info *link_info,
			  bfd_boolean *again)
{
  static value_map_hash_table *values = NULL;
  static bfd_boolean relocations_analyzed = FALSE;
  xtensa_relax_info *relax_info;

  if (!relocations_analyzed)
    {
      /* Do some overall initialization for relaxation.  */
      values = value_map_hash_table_init ();
      if (values == NULL)
	return FALSE;
      relaxing_section = TRUE;
      if (!analyze_relocations (link_info))
	return FALSE;
      relocations_analyzed = TRUE;
    }
  *again = FALSE;

  /* Don't mess with linker-created sections.  */
  if ((sec->flags & SEC_LINKER_CREATED) != 0)
    return TRUE;

  relax_info = get_xtensa_relax_info (sec);
  BFD_ASSERT (relax_info != NULL);

  switch (relax_info->visited)
    {
    case 0:
      /* Note: It would be nice to fold this pass into
	 analyze_relocations, but it is important for this step that the
	 sections be examined in link order.  */
      if (!compute_removed_literals (abfd, sec, link_info, values))
	return FALSE;
      *again = TRUE;
      break;

    case 1:
      if (values)
	value_map_hash_table_delete (values);
      values = NULL;
      if (!relax_section (abfd, sec, link_info))
	return FALSE;
      *again = TRUE;
      break;

    case 2:
      if (!relax_section_symbols (abfd, sec))
	return FALSE;
      break;
    }

  relax_info->visited++;
  return TRUE;
}


/* Initialization for relaxation.  */

/* This function is called once at the start of relaxation.  It scans
   all the input sections and marks the ones that are relaxable (i.e.,
   literal sections with L32R relocations against them), and then
   collects source_reloc information for all the relocations against
   those relaxable sections.  During this process, it also detects
   longcalls, i.e., calls relaxed by the assembler into indirect
   calls, that can be optimized back into direct calls.  Within each
   extended basic block (ebb) containing an optimized longcall, it
   computes a set of "text actions" that can be performed to remove
   the L32R associated with the longcall while optionally preserving
   branch target alignments.  */

static bfd_boolean
analyze_relocations (struct bfd_link_info *link_info)
{
  bfd *abfd;
  asection *sec;
  bfd_boolean is_relaxable = FALSE;

  /* Initialize the per-section relaxation info.  */
  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
    for (sec = abfd->sections; sec != NULL; sec = sec->next)
      {
	init_xtensa_relax_info (sec);
      }

  /* Mark relaxable sections (and count relocations against each one).  */
  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
    for (sec = abfd->sections; sec != NULL; sec = sec->next)
      {
	if (!find_relaxable_sections (abfd, sec, link_info, &is_relaxable))
	  return FALSE;
      }

  /* Bail out if there are no relaxable sections.  */
  if (!is_relaxable)
    return TRUE;

  /* Allocate space for source_relocs.  */
  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
    for (sec = abfd->sections; sec != NULL; sec = sec->next)
      {
	xtensa_relax_info *relax_info;

	relax_info = get_xtensa_relax_info (sec);
	if (relax_info->is_relaxable_literal_section
	    || relax_info->is_relaxable_asm_section)
	  {
	    relax_info->src_relocs = (source_reloc *)
	      bfd_malloc (relax_info->src_count * sizeof (source_reloc));
	  }
      }

  /* Collect info on relocations against each relaxable section.  */
  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
    for (sec = abfd->sections; sec != NULL; sec = sec->next)
      {
	if (!collect_source_relocs (abfd, sec, link_info))
	  return FALSE;
      }

  /* Compute the text actions.  */
  for (abfd = link_info->input_bfds; abfd != NULL; abfd = abfd->link_next)
    for (sec = abfd->sections; sec != NULL; sec = sec->next)
      {
	if (!compute_text_actions (abfd, sec, link_info))
	  return FALSE;
      }

  return TRUE;
}


/* Find all the sections that might be relaxed.  The motivation for
   this pass is that collect_source_relocs() needs to record _all_ the
   relocations that target each relaxable section.  That is expensive
   and unnecessary unless the target section is actually going to be
   relaxed.  This pass identifies all such sections by checking if
   they have L32Rs pointing to them.  In the process, the total number
   of relocations targeting each section is also counted so that we
   know how much space to allocate for source_relocs against each
   relaxable literal section.  */

static bfd_boolean
find_relaxable_sections (bfd *abfd,
			 asection *sec,
			 struct bfd_link_info *link_info,
			 bfd_boolean *is_relaxable_p)
{
  Elf_Internal_Rela *internal_relocs;
  bfd_byte *contents;
  bfd_boolean ok = TRUE;
  unsigned i;
  xtensa_relax_info *source_relax_info;

  internal_relocs = retrieve_internal_relocs (abfd, sec,
					      link_info->keep_memory);
  if (internal_relocs == NULL) 
    return ok;

  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec->size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  source_relax_info = get_xtensa_relax_info (sec);
  for (i = 0; i < sec->reloc_count; i++) 
    {
      Elf_Internal_Rela *irel = &internal_relocs[i];
      r_reloc r_rel;
      asection *target_sec;
      xtensa_relax_info *target_relax_info;

      /* If this section has not already been marked as "relaxable", and
	 if it contains any ASM_EXPAND relocations (marking expanded
	 longcalls) that can be optimized into direct calls, then mark
	 the section as "relaxable".  */
      if (source_relax_info
	  && !source_relax_info->is_relaxable_asm_section
	  && ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_EXPAND)
	{
	  bfd_boolean is_reachable = FALSE;
	  if (is_resolvable_asm_expansion (abfd, sec, contents, irel,
					   link_info, &is_reachable)
	      && is_reachable)
	    {
	      source_relax_info->is_relaxable_asm_section = TRUE;
	      *is_relaxable_p = TRUE;
	    }
	}

      r_reloc_init (&r_rel, abfd, irel, contents,
		    bfd_get_section_limit (abfd, sec));

      target_sec = r_reloc_get_section (&r_rel);
      target_relax_info = get_xtensa_relax_info (target_sec);
      if (!target_relax_info)
	continue;

      /* Count PC-relative operand relocations against the target section.
         Note: The conditions tested here must match the conditions under
	 which init_source_reloc is called in collect_source_relocs().  */
      if (is_operand_relocation (ELF32_R_TYPE (irel->r_info))
	  && (!is_alt_relocation (ELF32_R_TYPE (irel->r_info))
	      || is_l32r_relocation (abfd, sec, contents, irel)))
	target_relax_info->src_count++;

      if (is_l32r_relocation (abfd, sec, contents, irel)
	  && r_reloc_is_defined (&r_rel))
	{
	  /* Mark the target section as relaxable.  */
	  target_relax_info->is_relaxable_literal_section = TRUE;
	  *is_relaxable_p = TRUE;
	}
    }

 error_return:
  release_contents (sec, contents);
  release_internal_relocs (sec, internal_relocs);
  return ok;
}


/* Record _all_ the relocations that point to relaxable sections, and
   get rid of ASM_EXPAND relocs by either converting them to
   ASM_SIMPLIFY or by removing them.  */

static bfd_boolean
collect_source_relocs (bfd *abfd,
		       asection *sec,
		       struct bfd_link_info *link_info)
{
  Elf_Internal_Rela *internal_relocs;
  bfd_byte *contents;
  bfd_boolean ok = TRUE;
  unsigned i;
  bfd_size_type sec_size;

  internal_relocs = retrieve_internal_relocs (abfd, sec, 
					      link_info->keep_memory);
  if (internal_relocs == NULL) 
    return ok;

  sec_size = bfd_get_section_limit (abfd, sec);
  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec_size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  /* Record relocations against relaxable literal sections.  */
  for (i = 0; i < sec->reloc_count; i++) 
    {
      Elf_Internal_Rela *irel = &internal_relocs[i];
      r_reloc r_rel;
      asection *target_sec;
      xtensa_relax_info *target_relax_info;

      r_reloc_init (&r_rel, abfd, irel, contents, sec_size);

      target_sec = r_reloc_get_section (&r_rel);
      target_relax_info = get_xtensa_relax_info (target_sec);

      if (target_relax_info
	  && (target_relax_info->is_relaxable_literal_section
	      || target_relax_info->is_relaxable_asm_section))
	{
	  xtensa_opcode opcode = XTENSA_UNDEFINED;
	  int opnd = -1;
	  bfd_boolean is_abs_literal = FALSE;

	  if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
	    {
	      /* None of the current alternate relocs are PC-relative,
		 and only PC-relative relocs matter here.  However, we
		 still need to record the opcode for literal
		 coalescing.  */
	      opcode = get_relocation_opcode (abfd, sec, contents, irel);
	      if (opcode == get_l32r_opcode ())
		{
		  is_abs_literal = TRUE;
		  opnd = 1;
		}
	      else
		opcode = XTENSA_UNDEFINED;
	    }
	  else if (is_operand_relocation (ELF32_R_TYPE (irel->r_info)))
	    {
	      opcode = get_relocation_opcode (abfd, sec, contents, irel);
	      opnd = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
	    }

	  if (opcode != XTENSA_UNDEFINED)
	    {
	      int src_next = target_relax_info->src_next++;
	      source_reloc *s_reloc = &target_relax_info->src_relocs[src_next];

	      init_source_reloc (s_reloc, sec, &r_rel, opcode, opnd,
				 is_abs_literal);
	    }
	}
    }

  /* Now get rid of ASM_EXPAND relocations.  At this point, the
     src_relocs array for the target literal section may still be
     incomplete, but it must at least contain the entries for the L32R
     relocations associated with ASM_EXPANDs because they were just
     added in the preceding loop over the relocations.  */

  for (i = 0; i < sec->reloc_count; i++) 
    {
      Elf_Internal_Rela *irel = &internal_relocs[i];
      bfd_boolean is_reachable;

      if (!is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info,
					&is_reachable))
	continue;

      if (is_reachable)
	{
	  Elf_Internal_Rela *l32r_irel;
	  r_reloc r_rel;
	  asection *target_sec;
	  xtensa_relax_info *target_relax_info;

	  /* Mark the source_reloc for the L32R so that it will be
	     removed in compute_removed_literals(), along with the
	     associated literal.  */
	  l32r_irel = find_associated_l32r_irel (abfd, sec, contents,
						 irel, internal_relocs);
	  if (l32r_irel == NULL)
	    continue;

	  r_reloc_init (&r_rel, abfd, l32r_irel, contents, sec_size);

	  target_sec = r_reloc_get_section (&r_rel);
	  target_relax_info = get_xtensa_relax_info (target_sec);

	  if (target_relax_info
	      && (target_relax_info->is_relaxable_literal_section
		  || target_relax_info->is_relaxable_asm_section))
	    {
	      source_reloc *s_reloc;

	      /* Search the source_relocs for the entry corresponding to
		 the l32r_irel.  Note: The src_relocs array is not yet
		 sorted, but it wouldn't matter anyway because we're
		 searching by source offset instead of target offset.  */
	      s_reloc = find_source_reloc (target_relax_info->src_relocs, 
					   target_relax_info->src_next,
					   sec, l32r_irel);
	      BFD_ASSERT (s_reloc);
	      s_reloc->is_null = TRUE;
	    }

	  /* Convert this reloc to ASM_SIMPLIFY.  */
	  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
				       R_XTENSA_ASM_SIMPLIFY);
	  l32r_irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);

	  pin_internal_relocs (sec, internal_relocs);
	}
      else
	{
	  /* It is resolvable but doesn't reach.  We resolve now
	     by eliminating the relocation -- the call will remain
	     expanded into L32R/CALLX.  */
	  irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
	  pin_internal_relocs (sec, internal_relocs);
	}
    }

 error_return:
  release_contents (sec, contents);
  release_internal_relocs (sec, internal_relocs);
  return ok;
}


/* Return TRUE if the asm expansion can be resolved.  Generally it can
   be resolved on a final link or when a partial link locates it in the
   same section as the target.  Set "is_reachable" flag if the target of
   the call is within the range of a direct call, given the current VMA
   for this section and the target section.  */

bfd_boolean
is_resolvable_asm_expansion (bfd *abfd,
			     asection *sec,
			     bfd_byte *contents,
			     Elf_Internal_Rela *irel,
			     struct bfd_link_info *link_info,
			     bfd_boolean *is_reachable_p)
{
  asection *target_sec;
  bfd_vma target_offset;
  r_reloc r_rel;
  xtensa_opcode opcode, direct_call_opcode;
  bfd_vma self_address;
  bfd_vma dest_address;
  bfd_boolean uses_l32r;
  bfd_size_type sec_size;

  *is_reachable_p = FALSE;

  if (contents == NULL)
    return FALSE;

  if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_EXPAND) 
    return FALSE;

  sec_size = bfd_get_section_limit (abfd, sec);
  opcode = get_expanded_call_opcode (contents + irel->r_offset,
				     sec_size - irel->r_offset, &uses_l32r);
  /* Optimization of longcalls that use CONST16 is not yet implemented.  */
  if (!uses_l32r)
    return FALSE;
  
  direct_call_opcode = swap_callx_for_call_opcode (opcode);
  if (direct_call_opcode == XTENSA_UNDEFINED)
    return FALSE;

  /* Check and see that the target resolves.  */
  r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
  if (!r_reloc_is_defined (&r_rel))
    return FALSE;

  target_sec = r_reloc_get_section (&r_rel);
  target_offset = r_rel.target_offset;

  /* If the target is in a shared library, then it doesn't reach.  This
     isn't supposed to come up because the compiler should never generate
     non-PIC calls on systems that use shared libraries, but the linker
     shouldn't crash regardless.  */
  if (!target_sec->output_section)
    return FALSE;
      
  /* For relocatable sections, we can only simplify when the output
     section of the target is the same as the output section of the
     source.  */
  if (link_info->relocatable
      && (target_sec->output_section != sec->output_section
	  || is_reloc_sym_weak (abfd, irel)))
    return FALSE;

  self_address = (sec->output_section->vma
		  + sec->output_offset + irel->r_offset + 3);
  dest_address = (target_sec->output_section->vma
		  + target_sec->output_offset + target_offset);
      
  *is_reachable_p = pcrel_reloc_fits (direct_call_opcode, 0,
				      self_address, dest_address);

  if ((self_address >> CALL_SEGMENT_BITS) !=
      (dest_address >> CALL_SEGMENT_BITS))
    return FALSE;

  return TRUE;
}


static Elf_Internal_Rela *
find_associated_l32r_irel (bfd *abfd,
			   asection *sec,
			   bfd_byte *contents,
			   Elf_Internal_Rela *other_irel,
			   Elf_Internal_Rela *internal_relocs)
{
  unsigned i;

  for (i = 0; i < sec->reloc_count; i++) 
    {
      Elf_Internal_Rela *irel = &internal_relocs[i];

      if (irel == other_irel)
	continue;
      if (irel->r_offset != other_irel->r_offset)
	continue;
      if (is_l32r_relocation (abfd, sec, contents, irel))
	return irel;
    }

  return NULL;
}


/* The compute_text_actions function will build a list of potential
   transformation actions for code in the extended basic block of each
   longcall that is optimized to a direct call.  From this list we
   generate a set of actions to actually perform that optimizes for
   space and, if not using size_opt, maintains branch target
   alignments.

   These actions to be performed are placed on a per-section list.
   The actual changes are performed by relax_section() in the second
   pass.  */

bfd_boolean
compute_text_actions (bfd *abfd,
		      asection *sec,
		      struct bfd_link_info *link_info)
{
  xtensa_relax_info *relax_info;
  bfd_byte *contents;
  Elf_Internal_Rela *internal_relocs;
  bfd_boolean ok = TRUE;
  unsigned i;
  property_table_entry *prop_table = 0;
  int ptblsize = 0;
  bfd_size_type sec_size;
  static bfd_boolean no_insn_move = FALSE;

  if (no_insn_move)
    return ok;

  /* Do nothing if the section contains no optimized longcalls.  */
  relax_info = get_xtensa_relax_info (sec);
  BFD_ASSERT (relax_info);
  if (!relax_info->is_relaxable_asm_section)
    return ok;

  internal_relocs = retrieve_internal_relocs (abfd, sec,
					      link_info->keep_memory);

  if (internal_relocs)
    qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
	   internal_reloc_compare);

  sec_size = bfd_get_section_limit (abfd, sec);
  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec_size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
					XTENSA_PROP_SEC_NAME, FALSE);
  if (ptblsize < 0)
    {
      ok = FALSE;
      goto error_return;
    }

  for (i = 0; i < sec->reloc_count; i++)
    {
      Elf_Internal_Rela *irel = &internal_relocs[i];
      bfd_vma r_offset;
      property_table_entry *the_entry;
      int ptbl_idx;
      ebb_t *ebb;
      ebb_constraint ebb_table;
      bfd_size_type simplify_size;

      if (irel && ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_SIMPLIFY)
	continue;
      r_offset = irel->r_offset;

      simplify_size = get_asm_simplify_size (contents, sec_size, r_offset);
      if (simplify_size == 0)
	{
	  (*_bfd_error_handler)
	    (_("%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"),
	     sec->owner, sec, r_offset);
	  continue;
	}

      /* If the instruction table is not around, then don't do this
	 relaxation.  */
      the_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
						  sec->vma + irel->r_offset);
      if (the_entry == NULL || XTENSA_NO_NOP_REMOVAL)
	{
	  text_action_add (&relax_info->action_list,
			   ta_convert_longcall, sec, r_offset,
			   0);
	  continue;
	}

      /* If the next longcall happens to be at the same address as an
	 unreachable section of size 0, then skip forward.  */
      ptbl_idx = the_entry - prop_table;
      while ((the_entry->flags & XTENSA_PROP_UNREACHABLE)
	     && the_entry->size == 0
	     && ptbl_idx + 1 < ptblsize
	     && (prop_table[ptbl_idx + 1].address
		 == prop_table[ptbl_idx].address))
	{
	  ptbl_idx++;
	  the_entry++;
	}

      if (the_entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM)
	  /* NO_REORDER is OK */
	continue;

      init_ebb_constraint (&ebb_table);
      ebb = &ebb_table.ebb;
      init_ebb (ebb, sec, contents, sec_size, prop_table, ptblsize,
		internal_relocs, sec->reloc_count);
      ebb->start_offset = r_offset + simplify_size;
      ebb->end_offset = r_offset + simplify_size;
      ebb->start_ptbl_idx = ptbl_idx;
      ebb->end_ptbl_idx = ptbl_idx;
      ebb->start_reloc_idx = i;
      ebb->end_reloc_idx = i;

      if (!extend_ebb_bounds (ebb)
	  || !compute_ebb_proposed_actions (&ebb_table)
	  || !compute_ebb_actions (&ebb_table)
	  || !check_section_ebb_pcrels_fit (abfd, sec, contents,
					    internal_relocs, &ebb_table)
	  || !check_section_ebb_reduces (&ebb_table))
	{
	  /* If anything goes wrong or we get unlucky and something does
	     not fit, with our plan because of expansion between
	     critical branches, just convert to a NOP.  */

	  text_action_add (&relax_info->action_list,
			   ta_convert_longcall, sec, r_offset, 0);
	  i = ebb_table.ebb.end_reloc_idx;
	  free_ebb_constraint (&ebb_table);
	  continue;
	}

      text_action_add_proposed (&relax_info->action_list, &ebb_table, sec);

      /* Update the index so we do not go looking at the relocations
	 we have already processed.  */
      i = ebb_table.ebb.end_reloc_idx;
      free_ebb_constraint (&ebb_table);
    }

#if DEBUG
  if (relax_info->action_list.head)
    print_action_list (stderr, &relax_info->action_list);
#endif

error_return:
  release_contents (sec, contents);
  release_internal_relocs (sec, internal_relocs);
  if (prop_table)
    free (prop_table);

  return ok;
}


/* Find all of the possible actions for an extended basic block.  */

bfd_boolean
compute_ebb_proposed_actions (ebb_constraint *ebb_table)
{
  const ebb_t *ebb = &ebb_table->ebb;
  unsigned rel_idx = ebb->start_reloc_idx;
  property_table_entry *entry, *start_entry, *end_entry;

  start_entry = &ebb->ptbl[ebb->start_ptbl_idx];
  end_entry = &ebb->ptbl[ebb->end_ptbl_idx];

  for (entry = start_entry; entry <= end_entry; entry++)
    {
      bfd_vma offset, start_offset, end_offset;
      bfd_size_type insn_len;

      start_offset = entry->address - ebb->sec->vma;
      end_offset = entry->address + entry->size - ebb->sec->vma;

      if (entry == start_entry)
	start_offset = ebb->start_offset;
      if (entry == end_entry)
	end_offset = ebb->end_offset;
      offset = start_offset;

      if (offset == entry->address - ebb->sec->vma
	  && (entry->flags & XTENSA_PROP_INSN_BRANCH_TARGET) != 0)
	{
	  enum ebb_target_enum align_type = EBB_DESIRE_TGT_ALIGN;
	  BFD_ASSERT (offset != end_offset);
	  if (offset == end_offset)
	    return FALSE;

	  insn_len = insn_decode_len (ebb->contents, ebb->content_length,
				      offset);

	  /* Propose no actions for a section with an undecodable offset.  */
	  if (insn_len == 0) 
	    {
	      (*_bfd_error_handler)
		(_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
		 ebb->sec->owner, ebb->sec, offset);
	      return FALSE;
	    }
	  if (check_branch_target_aligned_address (offset, insn_len))
	    align_type = EBB_REQUIRE_TGT_ALIGN;

	  ebb_propose_action (ebb_table, align_type, 0,
			      ta_none, offset, 0, TRUE);
	}

      while (offset != end_offset)
	{
	  Elf_Internal_Rela *irel;
	  xtensa_opcode opcode;

	  while (rel_idx < ebb->end_reloc_idx
		 && (ebb->relocs[rel_idx].r_offset < offset
		     || (ebb->relocs[rel_idx].r_offset == offset
			 && (ELF32_R_TYPE (ebb->relocs[rel_idx].r_info)
			     != R_XTENSA_ASM_SIMPLIFY))))
	    rel_idx++;

	  /* Check for longcall.  */
	  irel = &ebb->relocs[rel_idx];
	  if (irel->r_offset == offset
	      && ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_SIMPLIFY)
	    {
	      bfd_size_type simplify_size;

	      simplify_size = get_asm_simplify_size (ebb->contents, 
						     ebb->content_length,
						     irel->r_offset);
	      if (simplify_size == 0)
		{
		  (*_bfd_error_handler)
		    (_("%B(%A+0x%lx): could not decode instruction for XTENSA_ASM_SIMPLIFY relocation; possible configuration mismatch"),
		     ebb->sec->owner, ebb->sec, offset);
		  return FALSE;
		}

	      ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
				  ta_convert_longcall, offset, 0, TRUE);
	      
	      offset += simplify_size;
	      continue;
	    }

	  insn_len = insn_decode_len (ebb->contents, ebb->content_length,
				      offset);
	  /* If the instruction is undecodable, then report an error.  */
	  if (insn_len == 0)
	    {
	      (*_bfd_error_handler)
		(_("%B(%A+0x%lx): could not decode instruction; possible configuration mismatch"),
		 ebb->sec->owner, ebb->sec, offset);
	      return FALSE;
	    }
	    
	  if ((entry->flags & XTENSA_PROP_INSN_NO_DENSITY) == 0
	      && (entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) == 0
	      && narrow_instruction (ebb->contents, ebb->content_length,
				     offset, FALSE))
	    {
	      /* Add an instruction narrow action.  */
	      ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
				  ta_narrow_insn, offset, 0, FALSE);
	      offset += insn_len;
	      continue;
	    }
	  if ((entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM) == 0
	      && widen_instruction (ebb->contents, ebb->content_length,
				    offset, FALSE))
	    {
	      /* Add an instruction widen action.  */
	      ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
				  ta_widen_insn, offset, 0, FALSE);
	      offset += insn_len;
	      continue;
	    }
	  opcode = insn_decode_opcode (ebb->contents, ebb->content_length,
				       offset, 0);
	  if (xtensa_opcode_is_loop (xtensa_default_isa, opcode))
	    {
	      /* Check for branch targets.  */
	      ebb_propose_action (ebb_table, EBB_REQUIRE_LOOP_ALIGN, 0,
				  ta_none, offset, 0, TRUE);
	      offset += insn_len;
	      continue;
	    }

	  offset += insn_len;
	}
    }

  if (ebb->ends_unreachable)
    {
      ebb_propose_action (ebb_table, EBB_NO_ALIGN, 0,
			  ta_fill, ebb->end_offset, 0, TRUE);
    }

  return TRUE;
}


/* After all of the information has collected about the
   transformations possible in an EBB, compute the appropriate actions
   here in compute_ebb_actions.  We still must check later to make
   sure that the actions do not break any relocations.  The algorithm
   used here is pretty greedy.  Basically, it removes as many no-ops
   as possible so that the end of the EBB has the same alignment
   characteristics as the original.  First, it uses narrowing, then
   fill space at the end of the EBB, and finally widenings.  If that
   does not work, it tries again with one fewer no-op removed.  The
   optimization will only be performed if all of the branch targets
   that were aligned before transformation are also aligned after the
   transformation.

   When the size_opt flag is set, ignore the branch target alignments,
   narrow all wide instructions, and remove all no-ops unless the end
   of the EBB prevents it.  */

bfd_boolean
compute_ebb_actions (ebb_constraint *ebb_table)
{
  unsigned i = 0;
  unsigned j;
  int removed_bytes = 0;
  ebb_t *ebb = &ebb_table->ebb;
  unsigned seg_idx_start = 0;
  unsigned seg_idx_end = 0;

  /* We perform this like the assembler relaxation algorithm: Start by
     assuming all instructions are narrow and all no-ops removed; then
     walk through....  */

  /* For each segment of this that has a solid constraint, check to
     see if there are any combinations that will keep the constraint.
     If so, use it.  */
  for (seg_idx_end = 0; seg_idx_end < ebb_table->action_count; seg_idx_end++)
    {
      bfd_boolean requires_text_end_align = FALSE;
      unsigned longcall_count = 0;
      unsigned longcall_convert_count = 0;
      unsigned narrowable_count = 0;
      unsigned narrowable_convert_count = 0;
      unsigned widenable_count = 0;
      unsigned widenable_convert_count = 0;

      proposed_action *action = NULL;
      int align = (1 << ebb_table->ebb.sec->alignment_power);

      seg_idx_start = seg_idx_end;

      for (i = seg_idx_start; i < ebb_table->action_count; i++)
	{
	  action = &ebb_table->actions[i];
	  if (action->action == ta_convert_longcall)
	    longcall_count++;
	  if (action->action == ta_narrow_insn)
	    narrowable_count++;
	  if (action->action == ta_widen_insn)
	    widenable_count++;
	  if (action->action == ta_fill)
	    break;
	  if (action->align_type == EBB_REQUIRE_LOOP_ALIGN)
	    break;
	  if (action->align_type == EBB_REQUIRE_TGT_ALIGN
	      && !elf32xtensa_size_opt)
	    break;
	}
      seg_idx_end = i;

      if (seg_idx_end == ebb_table->action_count && !ebb->ends_unreachable)
	requires_text_end_align = TRUE;

      if (elf32xtensa_size_opt && !requires_text_end_align
	  && action->align_type != EBB_REQUIRE_LOOP_ALIGN
	  && action->align_type != EBB_REQUIRE_TGT_ALIGN)
	{
	  longcall_convert_count = longcall_count;
	  narrowable_convert_count = narrowable_count;
	  widenable_convert_count = 0;
	}
      else
	{
	  /* There is a constraint.  Convert the max number of longcalls.  */
	  narrowable_convert_count = 0;
	  longcall_convert_count = 0;
	  widenable_convert_count = 0;

	  for (j = 0; j < longcall_count; j++)
	    {
	      int removed = (longcall_count - j) * 3 & (align - 1);
	      unsigned desire_narrow = (align - removed) & (align - 1);
	      unsigned desire_widen = removed;
	      if (desire_narrow <= narrowable_count)
		{
		  narrowable_convert_count = desire_narrow;
		  narrowable_convert_count +=
		    (align * ((narrowable_count - narrowable_convert_count)
			      / align));
		  longcall_convert_count = (longcall_count - j);
		  widenable_convert_count = 0;
		  break;
		}
	      if (desire_widen <= widenable_count && !elf32xtensa_size_opt)
		{
		  narrowable_convert_count = 0;
		  longcall_convert_count = longcall_count - j;
		  widenable_convert_count = desire_widen;
		  break;
		}
	    }
	}

      /* Now the number of conversions are saved.  Do them.  */
      for (i = seg_idx_start; i < seg_idx_end; i++)
	{
	  action = &ebb_table->actions[i];
	  switch (action->action)
	    {
	    case ta_convert_longcall:
	      if (longcall_convert_count != 0)
		{
		  action->action = ta_remove_longcall;
		  action->do_action = TRUE;
		  action->removed_bytes += 3;
		  longcall_convert_count--;
		}
	      break;
	    case ta_narrow_insn:
	      if (narrowable_convert_count != 0)
		{
		  action->do_action = TRUE;
		  action->removed_bytes += 1;
		  narrowable_convert_count--;
		}
	      break;
	    case ta_widen_insn:
	      if (widenable_convert_count != 0)
		{
		  action->do_action = TRUE;
		  action->removed_bytes -= 1;
		  widenable_convert_count--;
		}
	      break;
	    default:
	      break;
	    }
	}
    }

  /* Now we move on to some local opts.  Try to remove each of the
     remaining longcalls.  */

  if (ebb_table->ebb.ends_section || ebb_table->ebb.ends_unreachable)
    {
      removed_bytes = 0;
      for (i = 0; i < ebb_table->action_count; i++)
	{
	  int old_removed_bytes = removed_bytes;
	  proposed_action *action = &ebb_table->actions[i];

	  if (action->do_action && action->action == ta_convert_longcall)
	    {
	      bfd_boolean bad_alignment = FALSE;
	      removed_bytes += 3;
	      for (j = i + 1; j < ebb_table->action_count; j++)
		{
		  proposed_action *new_action = &ebb_table->actions[j];
		  bfd_vma offset = new_action->offset;
		  if (new_action->align_type == EBB_REQUIRE_TGT_ALIGN)
		    {
		      if (!check_branch_target_aligned
			  (ebb_table->ebb.contents,
			   ebb_table->ebb.content_length,
			   offset, offset - removed_bytes))
			{
			  bad_alignment = TRUE;
			  break;
			}
		    }
		  if (new_action->align_type == EBB_REQUIRE_LOOP_ALIGN)
		    {
		      if (!check_loop_aligned (ebb_table->ebb.contents,
					       ebb_table->ebb.content_length,
					       offset,
					       offset - removed_bytes))
			{
			  bad_alignment = TRUE;
			  break;
			}
		    }
		  if (new_action->action == ta_narrow_insn
		      && !new_action->do_action
		      && ebb_table->ebb.sec->alignment_power == 2)
		    {
		      /* Narrow an instruction and we are done.  */
		      new_action->do_action = TRUE;
		      new_action->removed_bytes += 1;
		      bad_alignment = FALSE;
		      break;
		    }
		  if (new_action->action == ta_widen_insn
		      && new_action->do_action
		      && ebb_table->ebb.sec->alignment_power == 2)
		    {
		      /* Narrow an instruction and we are done.  */
		      new_action->do_action = FALSE;
		      new_action->removed_bytes += 1;
		      bad_alignment = FALSE;
		      break;
		    }
		}
	      if (!bad_alignment)
		{
		  action->removed_bytes += 3;
		  action->action = ta_remove_longcall;
		  action->do_action = TRUE;
		}
	    }
	  removed_bytes = old_removed_bytes;
	  if (action->do_action)
	    removed_bytes += action->removed_bytes;
	}
    }

  removed_bytes = 0;
  for (i = 0; i < ebb_table->action_count; ++i)
    {
      proposed_action *action = &ebb_table->actions[i];
      if (action->do_action)
	removed_bytes += action->removed_bytes;
    }

  if ((removed_bytes % (1 << ebb_table->ebb.sec->alignment_power)) != 0
      && ebb->ends_unreachable)
    {
      proposed_action *action;
      int br;
      int extra_space;

      BFD_ASSERT (ebb_table->action_count != 0);
      action = &ebb_table->actions[ebb_table->action_count - 1];
      BFD_ASSERT (action->action == ta_fill);
      BFD_ASSERT (ebb->ends_unreachable->flags & XTENSA_PROP_UNREACHABLE);

      extra_space = compute_fill_extra_space (ebb->ends_unreachable);
      br = action->removed_bytes + removed_bytes + extra_space;
      br = br & ((1 << ebb->sec->alignment_power ) - 1);

      action->removed_bytes = extra_space - br;
    }
  return TRUE;
}


/* Use check_section_ebb_pcrels_fit to make sure that all of the
   relocations in a section will fit if a proposed set of actions
   are performed.  */

static bfd_boolean
check_section_ebb_pcrels_fit (bfd *abfd,
			      asection *sec,
			      bfd_byte *contents,
			      Elf_Internal_Rela *internal_relocs,
			      const ebb_constraint *constraint)
{
  unsigned i, j;
  Elf_Internal_Rela *irel;
  xtensa_relax_info *relax_info;

  relax_info = get_xtensa_relax_info (sec);

  for (i = 0; i < sec->reloc_count; i++)
    {
      r_reloc r_rel;
      bfd_vma orig_self_offset, orig_target_offset;
      bfd_vma self_offset, target_offset;
      int r_type;
      reloc_howto_type *howto;
      int self_removed_bytes, target_removed_bytes;

      irel = &internal_relocs[i];
      r_type = ELF32_R_TYPE (irel->r_info);

      howto = &elf_howto_table[r_type];
      /* We maintain the required invariant: PC-relative relocations
	 that fit before linking must fit after linking.  Thus we only
	 need to deal with relocations to the same section that are
	 PC-relative.  */
      if (ELF32_R_TYPE (irel->r_info) == R_XTENSA_ASM_SIMPLIFY
	  || !howto->pc_relative)
	continue;

      r_reloc_init (&r_rel, abfd, irel, contents,
		    bfd_get_section_limit (abfd, sec));

      if (r_reloc_get_section (&r_rel) != sec)
	continue;

      orig_self_offset = irel->r_offset;
      orig_target_offset = r_rel.target_offset;

      self_offset = orig_self_offset;
      target_offset = orig_target_offset;

      if (relax_info)
	{
	  self_offset = offset_with_removed_text (&relax_info->action_list,
						  orig_self_offset);
	  target_offset = offset_with_removed_text (&relax_info->action_list,
						    orig_target_offset);
	}

      self_removed_bytes = 0;
      target_removed_bytes = 0;

      for (j = 0; j < constraint->action_count; ++j)
	{
	  proposed_action *action = &constraint->actions[j];
	  bfd_vma offset = action->offset;
	  int removed_bytes = action->removed_bytes;
	  if (offset < orig_self_offset
	      || (offset == orig_self_offset && action->action == ta_fill
		  && action->removed_bytes < 0))
	    self_removed_bytes += removed_bytes;
	  if (offset < orig_target_offset
	      || (offset == orig_target_offset && action->action == ta_fill
		  && action->removed_bytes < 0))
	    target_removed_bytes += removed_bytes;
	}
      self_offset -= self_removed_bytes;
      target_offset -= target_removed_bytes;

      /* Try to encode it.  Get the operand and check.  */
      if (is_alt_relocation (ELF32_R_TYPE (irel->r_info)))
	{
	  /* None of the current alternate relocs are PC-relative,
	     and only PC-relative relocs matter here.  */
	}
      else
	{
	  xtensa_opcode opcode;
	  int opnum;

	  opcode = get_relocation_opcode (abfd, sec, contents, irel);
	  if (opcode == XTENSA_UNDEFINED)
	    return FALSE;

	  opnum = get_relocation_opnd (opcode, ELF32_R_TYPE (irel->r_info));
	  if (opnum == XTENSA_UNDEFINED)
	    return FALSE;

	  if (!pcrel_reloc_fits (opcode, opnum, self_offset, target_offset))
	    return FALSE;
	}
    }

  return TRUE;
}


static bfd_boolean
check_section_ebb_reduces (const ebb_constraint *constraint)
{
  int removed = 0;
  unsigned i;

  for (i = 0; i < constraint->action_count; i++)
    {
      const proposed_action *action = &constraint->actions[i];
      if (action->do_action)
	removed += action->removed_bytes;
    }
  if (removed < 0)
    return FALSE;

  return TRUE;
}


void
text_action_add_proposed (text_action_list *l,
			  const ebb_constraint *ebb_table,
			  asection *sec)
{
  unsigned i;

  for (i = 0; i < ebb_table->action_count; i++)
    {
      proposed_action *action = &ebb_table->actions[i];

      if (!action->do_action)
	continue;
      switch (action->action)
	{
	case ta_remove_insn:
	case ta_remove_longcall:
	case ta_convert_longcall:
	case ta_narrow_insn:
	case ta_widen_insn:
	case ta_fill:
	case ta_remove_literal:
	  text_action_add (l, action->action, sec, action->offset,
			   action->removed_bytes);
	  break;
	case ta_none:
	  break;
	default:
	  BFD_ASSERT (0);
	  break;
	}
    }
}


int
compute_fill_extra_space (property_table_entry *entry)
{
  int fill_extra_space;

  if (!entry)
    return 0;

  if ((entry->flags & XTENSA_PROP_UNREACHABLE) == 0)
    return 0;

  fill_extra_space = entry->size;
  if ((entry->flags & XTENSA_PROP_ALIGN) != 0)
    {
      /* Fill bytes for alignment:
	 (2**n)-1 - (addr + (2**n)-1) & (2**n -1) */
      int pow = GET_XTENSA_PROP_ALIGNMENT (entry->flags);
      int nsm = (1 << pow) - 1;
      bfd_vma addr = entry->address + entry->size;
      bfd_vma align_fill = nsm - ((addr + nsm) & nsm);
      fill_extra_space += align_fill;
    }
  return fill_extra_space;
}


/* First relaxation pass.  */

/* If the section contains relaxable literals, check each literal to
   see if it has the same value as another literal that has already
   been seen, either in the current section or a previous one.  If so,
   add an entry to the per-section list of removed literals.  The
   actual changes are deferred until the next pass.  */

static bfd_boolean 
compute_removed_literals (bfd *abfd,
			  asection *sec,
			  struct bfd_link_info *link_info,
			  value_map_hash_table *values)
{
  xtensa_relax_info *relax_info;
  bfd_byte *contents;
  Elf_Internal_Rela *internal_relocs;
  source_reloc *src_relocs, *rel;
  bfd_boolean ok = TRUE;
  property_table_entry *prop_table = NULL;
  int ptblsize;
  int i, prev_i;
  bfd_boolean last_loc_is_prev = FALSE;
  bfd_vma last_target_offset = 0;
  section_cache_t target_sec_cache;
  bfd_size_type sec_size;

  init_section_cache (&target_sec_cache);

  /* Do nothing if it is not a relaxable literal section.  */
  relax_info = get_xtensa_relax_info (sec);
  BFD_ASSERT (relax_info);
  if (!relax_info->is_relaxable_literal_section)
    return ok;

  internal_relocs = retrieve_internal_relocs (abfd, sec, 
					      link_info->keep_memory);

  sec_size = bfd_get_section_limit (abfd, sec);
  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec_size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  /* Sort the source_relocs by target offset.  */
  src_relocs = relax_info->src_relocs;
  qsort (src_relocs, relax_info->src_count,
	 sizeof (source_reloc), source_reloc_compare);
  qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
	 internal_reloc_compare);

  ptblsize = xtensa_read_table_entries (abfd, sec, &prop_table,
					XTENSA_PROP_SEC_NAME, FALSE);
  if (ptblsize < 0)
    {
      ok = FALSE;
      goto error_return;
    }

  prev_i = -1;
  for (i = 0; i < relax_info->src_count; i++)
    {
      Elf_Internal_Rela *irel = NULL;

      rel = &src_relocs[i];
      if (get_l32r_opcode () != rel->opcode)
	continue;
      irel = get_irel_at_offset (sec, internal_relocs,
				 rel->r_rel.target_offset);

      /* If the relocation on this is not a simple R_XTENSA_32 or
	 R_XTENSA_PLT then do not consider it.  This may happen when
	 the difference of two symbols is used in a literal.  */
      if (irel && (ELF32_R_TYPE (irel->r_info) != R_XTENSA_32
		   && ELF32_R_TYPE (irel->r_info) != R_XTENSA_PLT))
	continue;

      /* If the target_offset for this relocation is the same as the
	 previous relocation, then we've already considered whether the
	 literal can be coalesced.  Skip to the next one....  */
      if (i != 0 && prev_i != -1
	  && src_relocs[i-1].r_rel.target_offset == rel->r_rel.target_offset)
	continue;
      prev_i = i;

      if (last_loc_is_prev && 
	  last_target_offset + 4 != rel->r_rel.target_offset)
	last_loc_is_prev = FALSE;

      /* Check if the relocation was from an L32R that is being removed
	 because a CALLX was converted to a direct CALL, and check if
	 there are no other relocations to the literal.  */
      if (is_removable_literal (rel, i, src_relocs, relax_info->src_count))
	{
	  if (!remove_dead_literal (abfd, sec, link_info, internal_relocs,
				    irel, rel, prop_table, ptblsize))
	    {
	      ok = FALSE;
	      goto error_return;
	    }
	  last_target_offset = rel->r_rel.target_offset;
	  continue;
	}

      if (!identify_literal_placement (abfd, sec, contents, link_info,
				       values, 
				       &last_loc_is_prev, irel, 
				       relax_info->src_count - i, rel,
				       prop_table, ptblsize,
				       &target_sec_cache, rel->is_abs_literal))
	{
	  ok = FALSE;
	  goto error_return;
	}
      last_target_offset = rel->r_rel.target_offset;
    }

#if DEBUG
  print_removed_literals (stderr, &relax_info->removed_list);
  print_action_list (stderr, &relax_info->action_list);
#endif /* DEBUG */

error_return:
  if (prop_table) free (prop_table);
  clear_section_cache (&target_sec_cache);

  release_contents (sec, contents);
  release_internal_relocs (sec, internal_relocs);
  return ok;
}


static Elf_Internal_Rela *
get_irel_at_offset (asection *sec,
		    Elf_Internal_Rela *internal_relocs,
		    bfd_vma offset)
{
  unsigned i;
  Elf_Internal_Rela *irel;
  unsigned r_type;
  Elf_Internal_Rela key;

  if (!internal_relocs) 
    return NULL;

  key.r_offset = offset;
  irel = bsearch (&key, internal_relocs, sec->reloc_count,
		  sizeof (Elf_Internal_Rela), internal_reloc_matches);
  if (!irel)
    return NULL;

  /* bsearch does not guarantee which will be returned if there are
     multiple matches.  We need the first that is not an alignment.  */
  i = irel - internal_relocs;
  while (i > 0)
    {
      if (internal_relocs[i-1].r_offset != offset)
	break;
      i--;
    }
  for ( ; i < sec->reloc_count; i++)
    {
      irel = &internal_relocs[i];
      r_type = ELF32_R_TYPE (irel->r_info);
      if (irel->r_offset == offset && r_type != R_XTENSA_NONE)
	return irel;
    }

  return NULL;
}


bfd_boolean
is_removable_literal (const source_reloc *rel,
		      int i,
		      const source_reloc *src_relocs,
		      int src_count)
{
  const source_reloc *curr_rel;
  if (!rel->is_null)
    return FALSE;
  
  for (++i; i < src_count; ++i)
    {
      curr_rel = &src_relocs[i];
      /* If all others have the same target offset....  */
      if (curr_rel->r_rel.target_offset != rel->r_rel.target_offset)
	return TRUE;

      if (!curr_rel->is_null
	  && !xtensa_is_property_section (curr_rel->source_sec)
	  && !(curr_rel->source_sec->flags & SEC_DEBUGGING))
	return FALSE;
    }
  return TRUE;
}


bfd_boolean 
remove_dead_literal (bfd *abfd,
		     asection *sec,
		     struct bfd_link_info *link_info,
		     Elf_Internal_Rela *internal_relocs,
		     Elf_Internal_Rela *irel,
		     source_reloc *rel,
		     property_table_entry *prop_table,
		     int ptblsize)
{
  property_table_entry *entry;
  xtensa_relax_info *relax_info;

  relax_info = get_xtensa_relax_info (sec);
  if (!relax_info)
    return FALSE;

  entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
					  sec->vma + rel->r_rel.target_offset);

  /* Mark the unused literal so that it will be removed.  */
  add_removed_literal (&relax_info->removed_list, &rel->r_rel, NULL);

  text_action_add (&relax_info->action_list,
		   ta_remove_literal, sec, rel->r_rel.target_offset, 4);

  /* If the section is 4-byte aligned, do not add fill.  */
  if (sec->alignment_power > 2) 
    {
      int fill_extra_space;
      bfd_vma entry_sec_offset;
      text_action *fa;
      property_table_entry *the_add_entry;
      int removed_diff;

      if (entry)
	entry_sec_offset = entry->address - sec->vma + entry->size;
      else
	entry_sec_offset = rel->r_rel.target_offset + 4;

      /* If the literal range is at the end of the section,
	 do not add fill.  */
      the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
						      entry_sec_offset);
      fill_extra_space = compute_fill_extra_space (the_add_entry);

      fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
      removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
						  -4, fill_extra_space);
      if (fa)
	adjust_fill_action (fa, removed_diff);
      else
	text_action_add (&relax_info->action_list,
			 ta_fill, sec, entry_sec_offset, removed_diff);
    }

  /* Zero out the relocation on this literal location.  */
  if (irel)
    {
      if (elf_hash_table (link_info)->dynamic_sections_created)
	shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);

      irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
      pin_internal_relocs (sec, internal_relocs);
    }

  /* Do not modify "last_loc_is_prev".  */
  return TRUE;
}


bfd_boolean 
identify_literal_placement (bfd *abfd,
			    asection *sec,
			    bfd_byte *contents,
			    struct bfd_link_info *link_info,
			    value_map_hash_table *values,
			    bfd_boolean *last_loc_is_prev_p,
			    Elf_Internal_Rela *irel,
			    int remaining_src_rels,
			    source_reloc *rel,
			    property_table_entry *prop_table,
			    int ptblsize,
			    section_cache_t *target_sec_cache,
			    bfd_boolean is_abs_literal)
{
  literal_value val;
  value_map *val_map;
  xtensa_relax_info *relax_info;
  bfd_boolean literal_placed = FALSE;
  r_reloc r_rel;
  unsigned long value;
  bfd_boolean final_static_link;
  bfd_size_type sec_size;

  relax_info = get_xtensa_relax_info (sec);
  if (!relax_info)
    return FALSE;

  sec_size = bfd_get_section_limit (abfd, sec);

  final_static_link =
    (!link_info->relocatable
     && !elf_hash_table (link_info)->dynamic_sections_created);

  /* The placement algorithm first checks to see if the literal is
     already in the value map.  If so and the value map is reachable
     from all uses, then the literal is moved to that location.  If
     not, then we identify the last location where a fresh literal was
     placed.  If the literal can be safely moved there, then we do so.
     If not, then we assume that the literal is not to move and leave
     the literal where it is, marking it as the last literal
     location.  */

  /* Find the literal value.  */
  value = 0;
  r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
  if (!irel)
    {
      BFD_ASSERT (rel->r_rel.target_offset < sec_size);
      value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset);
    }
  init_literal_value (&val, &r_rel, value, is_abs_literal);

  /* Check if we've seen another literal with the same value that
     is in the same output section.  */
  val_map = value_map_get_cached_value (values, &val, final_static_link);

  if (val_map
      && (r_reloc_get_section (&val_map->loc)->output_section
	  == sec->output_section)
      && relocations_reach (rel, remaining_src_rels, &val_map->loc)
      && coalesce_shared_literal (sec, rel, prop_table, ptblsize, val_map))
    {
      /* No change to last_loc_is_prev.  */
      literal_placed = TRUE;
    }

  /* For relocatable links, do not try to move literals.  To do it
     correctly might increase the number of relocations in an input
     section making the default relocatable linking fail.  */
  if (!link_info->relocatable && !literal_placed 
      && values->has_last_loc && !(*last_loc_is_prev_p))
    {
      asection *target_sec = r_reloc_get_section (&values->last_loc);
      if (target_sec && target_sec->output_section == sec->output_section)
	{
	  /* Increment the virtual offset.  */
	  r_reloc try_loc = values->last_loc;
	  try_loc.virtual_offset += 4;

	  /* There is a last loc that was in the same output section.  */
	  if (relocations_reach (rel, remaining_src_rels, &try_loc)
	      && move_shared_literal (sec, link_info, rel,
				      prop_table, ptblsize, 
				      &try_loc, &val, target_sec_cache))
	    {
	      values->last_loc.virtual_offset += 4;
	      literal_placed = TRUE;
	      if (!val_map)
		val_map = add_value_map (values, &val, &try_loc,
					 final_static_link);
	      else
		val_map->loc = try_loc;
	    }
	}
    }

  if (!literal_placed)
    {
      /* Nothing worked, leave the literal alone but update the last loc.  */
      values->has_last_loc = TRUE;
      values->last_loc = rel->r_rel;
      if (!val_map)
	val_map = add_value_map (values, &val, &rel->r_rel, final_static_link);
      else
	val_map->loc = rel->r_rel;
      *last_loc_is_prev_p = TRUE;
    }

  return TRUE;
}


/* Check if the original relocations (presumably on L32R instructions)
   identified by reloc[0..N] can be changed to reference the literal
   identified by r_rel.  If r_rel is out of range for any of the
   original relocations, then we don't want to coalesce the original
   literal with the one at r_rel.  We only check reloc[0..N], where the
   offsets are all the same as for reloc[0] (i.e., they're all
   referencing the same literal) and where N is also bounded by the
   number of remaining entries in the "reloc" array.  The "reloc" array
   is sorted by target offset so we know all the entries for the same
   literal will be contiguous.  */

static bfd_boolean
relocations_reach (source_reloc *reloc,
		   int remaining_relocs,
		   const r_reloc *r_rel)
{
  bfd_vma from_offset, source_address, dest_address;
  asection *sec;
  int i;

  if (!r_reloc_is_defined (r_rel))
    return FALSE;

  sec = r_reloc_get_section (r_rel);
  from_offset = reloc[0].r_rel.target_offset;

  for (i = 0; i < remaining_relocs; i++)
    {
      if (reloc[i].r_rel.target_offset != from_offset)
	break;

      /* Ignore relocations that have been removed.  */
      if (reloc[i].is_null)
	continue;

      /* The original and new output section for these must be the same
         in order to coalesce.  */
      if (r_reloc_get_section (&reloc[i].r_rel)->output_section
	  != sec->output_section)
	return FALSE;

      /* A literal with no PC-relative relocations can be moved anywhere.  */
      if (reloc[i].opnd != -1)
	{
	  /* Otherwise, check to see that it fits.  */
	  source_address = (reloc[i].source_sec->output_section->vma
			    + reloc[i].source_sec->output_offset
			    + reloc[i].r_rel.rela.r_offset);
	  dest_address = (sec->output_section->vma
			  + sec->output_offset
			  + r_rel->target_offset);

	  if (!pcrel_reloc_fits (reloc[i].opcode, reloc[i].opnd,
				 source_address, dest_address))
	    return FALSE;
	}
    }

  return TRUE;
}


/* Move a literal to another literal location because it is
   the same as the other literal value.  */

static bfd_boolean 
coalesce_shared_literal (asection *sec,
			 source_reloc *rel,
			 property_table_entry *prop_table,
			 int ptblsize,
			 value_map *val_map)
{
  property_table_entry *entry;
  text_action *fa;
  property_table_entry *the_add_entry;
  int removed_diff;
  xtensa_relax_info *relax_info;

  relax_info = get_xtensa_relax_info (sec);
  if (!relax_info)
    return FALSE;

  entry = elf_xtensa_find_property_entry
    (prop_table, ptblsize, sec->vma + rel->r_rel.target_offset);
  if (entry && (entry->flags & XTENSA_PROP_INSN_NO_TRANSFORM))
    return TRUE;

  /* Mark that the literal will be coalesced.  */
  add_removed_literal (&relax_info->removed_list, &rel->r_rel, &val_map->loc);

  text_action_add (&relax_info->action_list,
		   ta_remove_literal, sec, rel->r_rel.target_offset, 4);

  /* If the section is 4-byte aligned, do not add fill.  */
  if (sec->alignment_power > 2) 
    {
      int fill_extra_space;
      bfd_vma entry_sec_offset;

      if (entry)
	entry_sec_offset = entry->address - sec->vma + entry->size;
      else
	entry_sec_offset = rel->r_rel.target_offset + 4;

      /* If the literal range is at the end of the section,
	 do not add fill.  */
      fill_extra_space = 0;
      the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
						      entry_sec_offset);
      if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
	fill_extra_space = the_add_entry->size;

      fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
      removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
						  -4, fill_extra_space);
      if (fa)
	adjust_fill_action (fa, removed_diff);
      else
	text_action_add (&relax_info->action_list,
			 ta_fill, sec, entry_sec_offset, removed_diff);
    }

  return TRUE;
}


/* Move a literal to another location.  This may actually increase the
   total amount of space used because of alignments so we need to do
   this carefully.  Also, it may make a branch go out of range.  */

static bfd_boolean 
move_shared_literal (asection *sec,
		     struct bfd_link_info *link_info,
		     source_reloc *rel,
		     property_table_entry *prop_table,
		     int ptblsize,
		     const r_reloc *target_loc,
		     const literal_value *lit_value,
		     section_cache_t *target_sec_cache)
{
  property_table_entry *the_add_entry, *src_entry, *target_entry = NULL;
  text_action *fa, *target_fa;
  int removed_diff;
  xtensa_relax_info *relax_info, *target_relax_info;
  asection *target_sec;
  ebb_t *ebb;
  ebb_constraint ebb_table;
  bfd_boolean relocs_fit;

  /* If this routine always returns FALSE, the literals that cannot be
     coalesced will not be moved.  */
  if (elf32xtensa_no_literal_movement)
    return FALSE;

  relax_info = get_xtensa_relax_info (sec);
  if (!relax_info)
    return FALSE;

  target_sec = r_reloc_get_section (target_loc);
  target_relax_info = get_xtensa_relax_info (target_sec);

  /* Literals to undefined sections may not be moved because they
     must report an error.  */
  if (bfd_is_und_section (target_sec))
    return FALSE;

  src_entry = elf_xtensa_find_property_entry
    (prop_table, ptblsize, sec->vma + rel->r_rel.target_offset);

  if (!section_cache_section (target_sec_cache, target_sec, link_info))
    return FALSE;

  target_entry = elf_xtensa_find_property_entry
    (target_sec_cache->ptbl, target_sec_cache->pte_count, 
     target_sec->vma + target_loc->target_offset);

  if (!target_entry)
    return FALSE;

  /* Make sure that we have not broken any branches.  */
  relocs_fit = FALSE;

  init_ebb_constraint (&ebb_table);
  ebb = &ebb_table.ebb;
  init_ebb (ebb, target_sec_cache->sec, target_sec_cache->contents, 
	    target_sec_cache->content_length,
	    target_sec_cache->ptbl, target_sec_cache->pte_count,
	    target_sec_cache->relocs, target_sec_cache->reloc_count);

  /* Propose to add 4 bytes + worst-case alignment size increase to
     destination.  */
  ebb_propose_action (&ebb_table, EBB_NO_ALIGN, 0,
		      ta_fill, target_loc->target_offset,
		      -4 - (1 << target_sec->alignment_power), TRUE);

  /* Check all of the PC-relative relocations to make sure they still fit.  */
  relocs_fit = check_section_ebb_pcrels_fit (target_sec->owner, target_sec, 
					     target_sec_cache->contents,
					     target_sec_cache->relocs,
					     &ebb_table);

  if (!relocs_fit) 
    return FALSE;

  text_action_add_literal (&target_relax_info->action_list,
			   ta_add_literal, target_loc, lit_value, -4);

  if (target_sec->alignment_power > 2 && target_entry != src_entry) 
    {
      /* May need to add or remove some fill to maintain alignment.  */
      int fill_extra_space;
      bfd_vma entry_sec_offset;

      entry_sec_offset = 
	target_entry->address - target_sec->vma + target_entry->size;

      /* If the literal range is at the end of the section,
	 do not add fill.  */
      fill_extra_space = 0;
      the_add_entry =
	elf_xtensa_find_property_entry (target_sec_cache->ptbl,
					target_sec_cache->pte_count,
					entry_sec_offset);
      if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
	fill_extra_space = the_add_entry->size;

      target_fa = find_fill_action (&target_relax_info->action_list,
				    target_sec, entry_sec_offset);
      removed_diff = compute_removed_action_diff (target_fa, target_sec,
						  entry_sec_offset, 4,
						  fill_extra_space);
      if (target_fa)
	adjust_fill_action (target_fa, removed_diff);
      else
	text_action_add (&target_relax_info->action_list,
			 ta_fill, target_sec, entry_sec_offset, removed_diff);
    }

  /* Mark that the literal will be moved to the new location.  */
  add_removed_literal (&relax_info->removed_list, &rel->r_rel, target_loc);

  /* Remove the literal.  */
  text_action_add (&relax_info->action_list,
		   ta_remove_literal, sec, rel->r_rel.target_offset, 4);

  /* If the section is 4-byte aligned, do not add fill.  */
  if (sec->alignment_power > 2 && target_entry != src_entry) 
    {
      int fill_extra_space;
      bfd_vma entry_sec_offset;

      if (src_entry)
	entry_sec_offset = src_entry->address - sec->vma + src_entry->size;
      else
	entry_sec_offset = rel->r_rel.target_offset+4;

      /* If the literal range is at the end of the section,
	 do not add fill.  */
      fill_extra_space = 0;
      the_add_entry = elf_xtensa_find_property_entry (prop_table, ptblsize,
						      entry_sec_offset);
      if (the_add_entry && (the_add_entry->flags & XTENSA_PROP_UNREACHABLE))
	fill_extra_space = the_add_entry->size;

      fa = find_fill_action (&relax_info->action_list, sec, entry_sec_offset);
      removed_diff = compute_removed_action_diff (fa, sec, entry_sec_offset,
						  -4, fill_extra_space);
      if (fa)
	adjust_fill_action (fa, removed_diff);
      else
	text_action_add (&relax_info->action_list,
			 ta_fill, sec, entry_sec_offset, removed_diff);
    }

  return TRUE;
}


/* Second relaxation pass.  */

/* Modify all of the relocations to point to the right spot, and if this
   is a relaxable section, delete the unwanted literals and fix the
   section size.  */

bfd_boolean
relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info)
{
  Elf_Internal_Rela *internal_relocs;
  xtensa_relax_info *relax_info;
  bfd_byte *contents;
  bfd_boolean ok = TRUE;
  unsigned i;
  bfd_boolean rv = FALSE;
  bfd_boolean virtual_action;
  bfd_size_type sec_size;

  sec_size = bfd_get_section_limit (abfd, sec);
  relax_info = get_xtensa_relax_info (sec);
  BFD_ASSERT (relax_info);

  /* First translate any of the fixes that have been added already.  */
  translate_section_fixes (sec);

  /* Handle property sections (e.g., literal tables) specially.  */
  if (xtensa_is_property_section (sec))
    {
      BFD_ASSERT (!relax_info->is_relaxable_literal_section);
      return relax_property_section (abfd, sec, link_info);
    }

  internal_relocs = retrieve_internal_relocs (abfd, sec, 
					      link_info->keep_memory);
  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec_size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  if (internal_relocs)
    {
      for (i = 0; i < sec->reloc_count; i++)
	{
	  Elf_Internal_Rela *irel;
	  xtensa_relax_info *target_relax_info;
	  bfd_vma source_offset, old_source_offset;
	  r_reloc r_rel;
	  unsigned r_type;
	  asection *target_sec;

	  /* Locally change the source address.
	     Translate the target to the new target address.
	     If it points to this section and has been removed,
	     NULLify it.
	     Write it back.  */

	  irel = &internal_relocs[i];
	  source_offset = irel->r_offset;
	  old_source_offset = source_offset;

	  r_type = ELF32_R_TYPE (irel->r_info);
	  r_reloc_init (&r_rel, abfd, irel, contents,
			bfd_get_section_limit (abfd, sec));

	  /* If this section could have changed then we may need to
	     change the relocation's offset.  */

	  if (relax_info->is_relaxable_literal_section
	      || relax_info->is_relaxable_asm_section)
	    {
	      if (r_type != R_XTENSA_NONE
		  && find_removed_literal (&relax_info->removed_list,
					   irel->r_offset))
		{
		  /* Remove this relocation.  */
		  if (elf_hash_table (link_info)->dynamic_sections_created)
		    shrink_dynamic_reloc_sections (link_info, abfd, sec, irel);
		  irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
		  irel->r_offset = offset_with_removed_text
		    (&relax_info->action_list, irel->r_offset);
		  pin_internal_relocs (sec, internal_relocs);
		  continue;
		}

	      if (r_type == R_XTENSA_ASM_SIMPLIFY)
		{
		  text_action *action =
		    find_insn_action (&relax_info->action_list,
				      irel->r_offset);
		  if (action && (action->action == ta_convert_longcall
				 || action->action == ta_remove_longcall))
		    {
		      bfd_reloc_status_type retval;
		      char *error_message = NULL;

		      retval = contract_asm_expansion (contents, sec_size,
						       irel, &error_message);
		      if (retval != bfd_reloc_ok)
			{
			  (*link_info->callbacks->reloc_dangerous)
			    (link_info, error_message, abfd, sec,
			     irel->r_offset);
			  goto error_return;
			}
		      /* Update the action so that the code that moves
			 the contents will do the right thing.  */
		      if (action->action == ta_remove_longcall)
			action->action = ta_remove_insn;
		      else
			action->action = ta_none;
		      /* Refresh the info in the r_rel.  */
		      r_reloc_init (&r_rel, abfd, irel, contents, sec_size);
		      r_type = ELF32_R_TYPE (irel->r_info);
		    }
		}

	      source_offset = offset_with_removed_text
		(&relax_info->action_list, irel->r_offset);
	      irel->r_offset = source_offset;
	    }

	  /* If the target section could have changed then
	     we may need to change the relocation's target offset.  */

	  target_sec = r_reloc_get_section (&r_rel);
	  target_relax_info = get_xtensa_relax_info (target_sec);

	  if (target_relax_info
	      && (target_relax_info->is_relaxable_literal_section
		  || target_relax_info->is_relaxable_asm_section))
	    {
	      r_reloc new_reloc;
	      reloc_bfd_fix *fix;
	      bfd_vma addend_displacement;

	      translate_reloc (&r_rel, &new_reloc);

	      if (r_type == R_XTENSA_DIFF8
		  || r_type == R_XTENSA_DIFF16
		  || r_type == R_XTENSA_DIFF32)
		{
		  bfd_vma diff_value = 0, new_end_offset, diff_mask = 0;

		  if (bfd_get_section_limit (abfd, sec) < old_source_offset)
		    {
		      (*link_info->callbacks->reloc_dangerous)
			(link_info, _("invalid relocation address"),
			 abfd, sec, old_source_offset);
		      goto error_return;
		    }

		  switch (r_type)
		    {
		    case R_XTENSA_DIFF8:
		      diff_value =
			bfd_get_8 (abfd, &contents[old_source_offset]);
		      break;
		    case R_XTENSA_DIFF16:
		      diff_value =
			bfd_get_16 (abfd, &contents[old_source_offset]);
		      break;
		    case R_XTENSA_DIFF32:
		      diff_value =
			bfd_get_32 (abfd, &contents[old_source_offset]);
		      break;
		    }

		  new_end_offset = offset_with_removed_text
		    (&target_relax_info->action_list,
		     r_rel.target_offset + diff_value);
		  diff_value = new_end_offset - new_reloc.target_offset;

		  switch (r_type)
		    {
		    case R_XTENSA_DIFF8:
		      diff_mask = 0xff;
		      bfd_put_8 (abfd, diff_value,
				 &contents[old_source_offset]);
		      break;
		    case R_XTENSA_DIFF16:
		      diff_mask = 0xffff;
		      bfd_put_16 (abfd, diff_value,
				  &contents[old_source_offset]);
		      break;
		    case R_XTENSA_DIFF32:
		      diff_mask = 0xffffffff;
		      bfd_put_32 (abfd, diff_value,
				  &contents[old_source_offset]);
		      break;
		    }

		  /* Check for overflow.  */
		  if ((diff_value & ~diff_mask) != 0)
		    {
		      (*link_info->callbacks->reloc_dangerous)
			(link_info, _("overflow after relaxation"),
			 abfd, sec, old_source_offset);
		      goto error_return;
		    }

		  pin_contents (sec, contents);
		}

	      /* FIXME: If the relocation still references a section in
		 the same input file, the relocation should be modified
		 directly instead of adding a "fix" record.  */

	      addend_displacement =
		new_reloc.target_offset + new_reloc.virtual_offset;

	      fix = reloc_bfd_fix_init (sec, source_offset, r_type, 0,
					r_reloc_get_section (&new_reloc),
					addend_displacement, TRUE);
	      add_fix (sec, fix);
	    }

	  pin_internal_relocs (sec, internal_relocs);
	}
    }

  if ((relax_info->is_relaxable_literal_section
       || relax_info->is_relaxable_asm_section)
      && relax_info->action_list.head)
    {
      /* Walk through the planned actions and build up a table
	 of move, copy and fill records.  Use the move, copy and
	 fill records to perform the actions once.  */

      bfd_size_type size = sec->size;
      int removed = 0;
      bfd_size_type final_size, copy_size, orig_insn_size;
      bfd_byte *scratch = NULL;
      bfd_byte *dup_contents = NULL;
      bfd_size_type orig_size = size;
      bfd_vma orig_dot = 0;
      bfd_vma orig_dot_copied = 0; /* Byte copied already from
					    orig dot in physical memory.  */
      bfd_vma orig_dot_vo = 0; /* Virtual offset from orig_dot.  */
      bfd_vma dup_dot = 0;

      text_action *action = relax_info->action_list.head;

      final_size = sec->size;
      for (action = relax_info->action_list.head; action;
	   action = action->next)
	{
	  final_size -= action->removed_bytes;
	}

      scratch = (bfd_byte *) bfd_zmalloc (final_size);
      dup_contents = (bfd_byte *) bfd_zmalloc (final_size);

      /* The dot is the current fill location.  */
#if DEBUG
      print_action_list (stderr, &relax_info->action_list);
#endif

      for (action = relax_info->action_list.head; action;
	   action = action->next)
	{
	  virtual_action = FALSE;
	  if (action->offset > orig_dot)
	    {
	      orig_dot += orig_dot_copied;
	      orig_dot_copied = 0;
	      orig_dot_vo = 0;
	      /* Out of the virtual world.  */
	    }

	  if (action->offset > orig_dot)
	    {
	      copy_size = action->offset - orig_dot;
	      memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size);
	      orig_dot += copy_size;
	      dup_dot += copy_size;
	      BFD_ASSERT (action->offset == orig_dot);
	    }
	  else if (action->offset < orig_dot)
	    {
	      if (action->action == ta_fill
		  && action->offset - action->removed_bytes == orig_dot)
		{
		  /* This is OK because the fill only effects the dup_dot.  */
		}
	      else if (action->action == ta_add_literal)
		{
		  /* TBD.  Might need to handle this.  */
		}
	    }
	  if (action->offset == orig_dot)
	    {
	      if (action->virtual_offset > orig_dot_vo)
		{
		  if (orig_dot_vo == 0)
		    {
		      /* Need to copy virtual_offset bytes.  Probably four.  */
		      copy_size = action->virtual_offset - orig_dot_vo;
		      memmove (&dup_contents[dup_dot],
			       &contents[orig_dot], copy_size);
		      orig_dot_copied = copy_size;
		      dup_dot += copy_size;
		    }
		  virtual_action = TRUE;
		} 
	      else
		BFD_ASSERT (action->virtual_offset <= orig_dot_vo);
	    }
	  switch (action->action)
	    {
	    case ta_remove_literal:
	    case ta_remove_insn:
	      BFD_ASSERT (action->removed_bytes >= 0);
	      orig_dot += action->removed_bytes;
	      break;

	    case ta_narrow_insn:
	      orig_insn_size = 3;
	      copy_size = 2;
	      memmove (scratch, &contents[orig_dot], orig_insn_size);
	      BFD_ASSERT (action->removed_bytes == 1);
	      rv = narrow_instruction (scratch, final_size, 0, TRUE);
	      BFD_ASSERT (rv);
	      memmove (&dup_contents[dup_dot], scratch, copy_size);
	      orig_dot += orig_insn_size;
	      dup_dot += copy_size;
	      break;

	    case ta_fill:
	      if (action->removed_bytes >= 0)
		orig_dot += action->removed_bytes;
	      else
		{
		  /* Already zeroed in dup_contents.  Just bump the
		     counters.  */
		  dup_dot += (-action->removed_bytes);
		}
	      break;

	    case ta_none:
	      BFD_ASSERT (action->removed_bytes == 0);
	      break;

	    case ta_convert_longcall:
	    case ta_remove_longcall:
	      /* These will be removed or converted before we get here.  */
	      BFD_ASSERT (0);
	      break;

	    case ta_widen_insn:
	      orig_insn_size = 2;
	      copy_size = 3;
	      memmove (scratch, &contents[orig_dot], orig_insn_size);
	      BFD_ASSERT (action->removed_bytes == -1);
	      rv = widen_instruction (scratch, final_size, 0, TRUE);
	      BFD_ASSERT (rv);
	      memmove (&dup_contents[dup_dot], scratch, copy_size);
	      orig_dot += orig_insn_size;
	      dup_dot += copy_size;
	      break;

	    case ta_add_literal:
	      orig_insn_size = 0;
	      copy_size = 4;
	      BFD_ASSERT (action->removed_bytes == -4);
	      /* TBD -- place the literal value here and insert
		 into the table.  */
	      memset (&dup_contents[dup_dot], 0, 4);
	      pin_internal_relocs (sec, internal_relocs);
	      pin_contents (sec, contents);

	      if (!move_literal (abfd, link_info, sec, dup_dot, dup_contents,
				 relax_info, &internal_relocs, &action->value))
		goto error_return;

	      if (virtual_action) 
		orig_dot_vo += copy_size;

	      orig_dot += orig_insn_size;
	      dup_dot += copy_size;
	      break;

	    default:
	      /* Not implemented yet.  */
	      BFD_ASSERT (0);
	      break;
	    }

	  size -= action->removed_bytes;
	  removed += action->removed_bytes;
	  BFD_ASSERT (dup_dot <= final_size);
	  BFD_ASSERT (orig_dot <= orig_size);
	}

      orig_dot += orig_dot_copied;
      orig_dot_copied = 0;

      if (orig_dot != orig_size)
	{
	  copy_size = orig_size - orig_dot;
	  BFD_ASSERT (orig_size > orig_dot);
	  BFD_ASSERT (dup_dot + copy_size == final_size);
	  memmove (&dup_contents[dup_dot], &contents[orig_dot], copy_size);
	  orig_dot += copy_size;
	  dup_dot += copy_size;
	}
      BFD_ASSERT (orig_size == orig_dot);
      BFD_ASSERT (final_size == dup_dot);

      /* Move the dup_contents back.  */
      if (final_size > orig_size)
	{
	  /* Contents need to be reallocated.  Swap the dup_contents into
	     contents.  */
	  sec->contents = dup_contents;
	  free (contents);
	  contents = dup_contents;
	  pin_contents (sec, contents);
	}
      else
	{
	  BFD_ASSERT (final_size <= orig_size);
	  memset (contents, 0, orig_size);
	  memcpy (contents, dup_contents, final_size);
	  free (dup_contents);
	}
      free (scratch);
      pin_contents (sec, contents);

      sec->size = final_size;
    }

 error_return:
  release_internal_relocs (sec, internal_relocs);
  release_contents (sec, contents);
  return ok;
}


static bfd_boolean 
translate_section_fixes (asection *sec)
{
  xtensa_relax_info *relax_info;
  reloc_bfd_fix *r;

  relax_info = get_xtensa_relax_info (sec);
  if (!relax_info)
    return TRUE;

  for (r = relax_info->fix_list; r != NULL; r = r->next)
    if (!translate_reloc_bfd_fix (r))
      return FALSE;

  return TRUE;
}


/* Translate a fix given the mapping in the relax info for the target
   section.  If it has already been translated, no work is required.  */

static bfd_boolean 
translate_reloc_bfd_fix (reloc_bfd_fix *fix)
{
  reloc_bfd_fix new_fix;
  asection *sec;
  xtensa_relax_info *relax_info;
  removed_literal *removed;
  bfd_vma new_offset, target_offset;

  if (fix->translated)
    return TRUE;

  sec = fix->target_sec;
  target_offset = fix->target_offset;

  relax_info = get_xtensa_relax_info (sec);
  if (!relax_info)
    {
      fix->translated = TRUE;
      return TRUE;
    }

  new_fix = *fix;

  /* The fix does not need to be translated if the section cannot change.  */
  if (!relax_info->is_relaxable_literal_section
      && !relax_info->is_relaxable_asm_section)
    {
      fix->translated = TRUE;
      return TRUE;
    }

  /* If the literal has been moved and this relocation was on an
     opcode, then the relocation should move to the new literal
     location.  Otherwise, the relocation should move within the
     section.  */

  removed = FALSE;
  if (is_operand_relocation (fix->src_type))
    {
      /* Check if the original relocation is against a literal being
	 removed.  */
      removed = find_removed_literal (&relax_info->removed_list,
				      target_offset);
    }

  if (removed) 
    {
      asection *new_sec;

      /* The fact that there is still a relocation to this literal indicates
	 that the literal is being coalesced, not simply removed.  */
      BFD_ASSERT (removed->to.abfd != NULL);

      /* This was moved to some other address (possibly another section).  */
      new_sec = r_reloc_get_section (&removed->to);
      if (new_sec != sec) 
	{
	  sec = new_sec;
	  relax_info = get_xtensa_relax_info (sec);
	  if (!relax_info || 
	      (!relax_info->is_relaxable_literal_section
	       && !relax_info->is_relaxable_asm_section))
	    {
	      target_offset = removed->to.target_offset;
	      new_fix.target_sec = new_sec;
	      new_fix.target_offset = target_offset;
	      new_fix.translated = TRUE;
	      *fix = new_fix;
	      return TRUE;
	    }
	}
      target_offset = removed->to.target_offset;
      new_fix.target_sec = new_sec;
    }

  /* The target address may have been moved within its section.  */
  new_offset = offset_with_removed_text (&relax_info->action_list,
					 target_offset);

  new_fix.target_offset = new_offset;
  new_fix.target_offset = new_offset;
  new_fix.translated = TRUE;
  *fix = new_fix;
  return TRUE;
}


/* Fix up a relocation to take account of removed literals.  */

static void
translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel)
{
  asection *sec;
  xtensa_relax_info *relax_info;
  removed_literal *removed;
  bfd_vma new_offset, target_offset, removed_bytes;

  *new_rel = *orig_rel;

  if (!r_reloc_is_defined (orig_rel))
    return;
  sec = r_reloc_get_section (orig_rel);

  relax_info = get_xtensa_relax_info (sec);
  BFD_ASSERT (relax_info);

  if (!relax_info->is_relaxable_literal_section
      && !relax_info->is_relaxable_asm_section)
    return;

  target_offset = orig_rel->target_offset;

  removed = FALSE;
  if (is_operand_relocation (ELF32_R_TYPE (orig_rel->rela.r_info)))
    {
      /* Check if the original relocation is against a literal being
	 removed.  */
      removed = find_removed_literal (&relax_info->removed_list,
				      target_offset);
    }
  if (removed && removed->to.abfd)
    {
      asection *new_sec;

      /* The fact that there is still a relocation to this literal indicates
	 that the literal is being coalesced, not simply removed.  */
      BFD_ASSERT (removed->to.abfd != NULL);

      /* This was moved to some other address
	 (possibly in another section).  */
      *new_rel = removed->to;
      new_sec = r_reloc_get_section (new_rel);
      if (new_sec != sec)
	{
	  sec = new_sec;
	  relax_info = get_xtensa_relax_info (sec);
	  if (!relax_info
	      || (!relax_info->is_relaxable_literal_section
		  && !relax_info->is_relaxable_asm_section))
	    return;
	}
      target_offset = new_rel->target_offset;
    }

  /* ...and the target address may have been moved within its section.  */
  new_offset = offset_with_removed_text (&relax_info->action_list,
					 target_offset);

  /* Modify the offset and addend.  */
  removed_bytes = target_offset - new_offset;
  new_rel->target_offset = new_offset;
  new_rel->rela.r_addend -= removed_bytes;
}


/* For dynamic links, there may be a dynamic relocation for each
   literal.  The number of dynamic relocations must be computed in
   size_dynamic_sections, which occurs before relaxation.  When a
   literal is removed, this function checks if there is a corresponding
   dynamic relocation and shrinks the size of the appropriate dynamic
   relocation section accordingly.  At this point, the contents of the
   dynamic relocation sections have not yet been filled in, so there's
   nothing else that needs to be done.  */

static void
shrink_dynamic_reloc_sections (struct bfd_link_info *info,
			       bfd *abfd,
			       asection *input_section,
			       Elf_Internal_Rela *rel)
{
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  unsigned long r_symndx;
  int r_type;
  struct elf_link_hash_entry *h;
  bfd_boolean dynamic_symbol;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (abfd);

  r_type = ELF32_R_TYPE (rel->r_info);
  r_symndx = ELF32_R_SYM (rel->r_info);

  if (r_symndx < symtab_hdr->sh_info)
    h = NULL;
  else
    h = sym_hashes[r_symndx - symtab_hdr->sh_info];

  dynamic_symbol = xtensa_elf_dynamic_symbol_p (h, info);

  if ((r_type == R_XTENSA_32 || r_type == R_XTENSA_PLT)
      && (input_section->flags & SEC_ALLOC) != 0
      && (dynamic_symbol || info->shared))
    {
      bfd *dynobj;
      const char *srel_name;
      asection *srel;
      bfd_boolean is_plt = FALSE;

      dynobj = elf_hash_table (info)->dynobj;
      BFD_ASSERT (dynobj != NULL);

      if (dynamic_symbol && r_type == R_XTENSA_PLT)
	{
	  srel_name = ".rela.plt";
	  is_plt = TRUE;
	}
      else
	srel_name = ".rela.got";

      /* Reduce size of the .rela.* section by one reloc.  */
      srel = bfd_get_section_by_name (dynobj, srel_name);
      BFD_ASSERT (srel != NULL);
      BFD_ASSERT (srel->size >= sizeof (Elf32_External_Rela));
      srel->size -= sizeof (Elf32_External_Rela);

      if (is_plt)
	{
	  asection *splt, *sgotplt, *srelgot;
	  int reloc_index, chunk;

	  /* Find the PLT reloc index of the entry being removed.  This
	     is computed from the size of ".rela.plt".  It is needed to
	     figure out which PLT chunk to resize.  Usually "last index
	     = size - 1" since the index starts at zero, but in this
	     context, the size has just been decremented so there's no
	     need to subtract one.  */
	  reloc_index = srel->size / sizeof (Elf32_External_Rela);

	  chunk = reloc_index / PLT_ENTRIES_PER_CHUNK;
	  splt = elf_xtensa_get_plt_section (dynobj, chunk);
	  sgotplt = elf_xtensa_get_gotplt_section (dynobj, chunk);
	  BFD_ASSERT (splt != NULL && sgotplt != NULL);

	  /* Check if an entire PLT chunk has just been eliminated.  */
	  if (reloc_index % PLT_ENTRIES_PER_CHUNK == 0)
	    {
	      /* The two magic GOT entries for that chunk can go away.  */
	      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");
	      BFD_ASSERT (srelgot != NULL);
	      srelgot->reloc_count -= 2;
	      srelgot->size -= 2 * sizeof (Elf32_External_Rela);
	      sgotplt->size -= 8;

	      /* There should be only one entry left (and it will be
		 removed below).  */
	      BFD_ASSERT (sgotplt->size == 4);
	      BFD_ASSERT (splt->size == PLT_ENTRY_SIZE);
	    }

	  BFD_ASSERT (sgotplt->size >= 4);
	  BFD_ASSERT (splt->size >= PLT_ENTRY_SIZE);

	  sgotplt->size -= 4;
	  splt->size -= PLT_ENTRY_SIZE;
	}
    }
}


/* Take an r_rel and move it to another section.  This usually
   requires extending the interal_relocation array and pinning it.  If
   the original r_rel is from the same BFD, we can complete this here.
   Otherwise, we add a fix record to let the final link fix the
   appropriate address.  Contents and internal relocations for the
   section must be pinned after calling this routine.  */

static bfd_boolean
move_literal (bfd *abfd,
	      struct bfd_link_info *link_info,
	      asection *sec,
	      bfd_vma offset,
	      bfd_byte *contents,
	      xtensa_relax_info *relax_info,
	      Elf_Internal_Rela **internal_relocs_p,
	      const literal_value *lit)
{
  Elf_Internal_Rela *new_relocs = NULL;
  size_t new_relocs_count = 0;
  Elf_Internal_Rela this_rela;
  const r_reloc *r_rel;

  r_rel = &lit->r_rel;
  BFD_ASSERT (elf_section_data (sec)->relocs == *internal_relocs_p);

  if (r_reloc_is_const (r_rel))
    bfd_put_32 (abfd, lit->value, contents + offset);
  else
    {
      int r_type;
      unsigned i;
      asection *target_sec;
      reloc_bfd_fix *fix;
      unsigned insert_at;

      r_type = ELF32_R_TYPE (r_rel->rela.r_info);
      target_sec = r_reloc_get_section (r_rel);

      /* This is the difficult case.  We have to create a fix up.  */
      this_rela.r_offset = offset;
      this_rela.r_info = ELF32_R_INFO (0, r_type);
      this_rela.r_addend =
	r_rel->target_offset - r_reloc_get_target_offset (r_rel);
      bfd_put_32 (abfd, lit->value, contents + offset);

      /* Currently, we cannot move relocations during a relocatable link.  */
      BFD_ASSERT (!link_info->relocatable);
      fix = reloc_bfd_fix_init (sec, offset, r_type, r_rel->abfd,
				r_reloc_get_section (r_rel),
				r_rel->target_offset + r_rel->virtual_offset,
				FALSE);
      /* We also need to mark that relocations are needed here.  */
      sec->flags |= SEC_RELOC;

      translate_reloc_bfd_fix (fix);
      /* This fix has not yet been translated.  */
      add_fix (sec, fix);

      /* Add the relocation.  If we have already allocated our own
	 space for the relocations and we have room for more, then use
	 it.  Otherwise, allocate new space and move the literals.  */
      insert_at = sec->reloc_count;
      for (i = 0; i < sec->reloc_count; ++i)
	{
	  if (this_rela.r_offset < (*internal_relocs_p)[i].r_offset)
	    {
	      insert_at = i;
	      break;
	    }
	}

      if (*internal_relocs_p != relax_info->allocated_relocs
	  || sec->reloc_count + 1 > relax_info->allocated_relocs_count)
	{
	  BFD_ASSERT (relax_info->allocated_relocs == NULL
		      || sec->reloc_count == relax_info->relocs_count);

	  if (relax_info->allocated_relocs_count == 0) 
	    new_relocs_count = (sec->reloc_count + 2) * 2;
	  else
	    new_relocs_count = (relax_info->allocated_relocs_count + 2) * 2;

	  new_relocs = (Elf_Internal_Rela *)
	    bfd_zmalloc (sizeof (Elf_Internal_Rela) * (new_relocs_count));
	  if (!new_relocs)
	    return FALSE;

	  /* We could handle this more quickly by finding the split point.  */
	  if (insert_at != 0)
	    memcpy (new_relocs, *internal_relocs_p,
		    insert_at * sizeof (Elf_Internal_Rela));

	  new_relocs[insert_at] = this_rela;

	  if (insert_at != sec->reloc_count)
	    memcpy (new_relocs + insert_at + 1,
		    (*internal_relocs_p) + insert_at,
		    (sec->reloc_count - insert_at) 
		    * sizeof (Elf_Internal_Rela));

	  if (*internal_relocs_p != relax_info->allocated_relocs)
	    {
	      /* The first time we re-allocate, we can only free the
		 old relocs if they were allocated with bfd_malloc.
		 This is not true when keep_memory is in effect.  */
	      if (!link_info->keep_memory)
		free (*internal_relocs_p);
	    }
	  else
	    free (*internal_relocs_p);
	  relax_info->allocated_relocs = new_relocs;
	  relax_info->allocated_relocs_count = new_relocs_count;
	  elf_section_data (sec)->relocs = new_relocs;
	  sec->reloc_count++;
	  relax_info->relocs_count = sec->reloc_count;
	  *internal_relocs_p = new_relocs;
	}
      else
	{
	  if (insert_at != sec->reloc_count)
	    {
	      unsigned idx;
	      for (idx = sec->reloc_count; idx > insert_at; idx--)
		(*internal_relocs_p)[idx] = (*internal_relocs_p)[idx-1];
	    }
	  (*internal_relocs_p)[insert_at] = this_rela;
	  sec->reloc_count++;
	  if (relax_info->allocated_relocs)
	    relax_info->relocs_count = sec->reloc_count;
	}
    }
  return TRUE;
}


/* This is similar to relax_section except that when a target is moved,
   we shift addresses up.  We also need to modify the size.  This
   algorithm does NOT allow for relocations into the middle of the
   property sections.  */

static bfd_boolean
relax_property_section (bfd *abfd,
			asection *sec,
			struct bfd_link_info *link_info)
{
  Elf_Internal_Rela *internal_relocs;
  bfd_byte *contents;
  unsigned i, nexti;
  bfd_boolean ok = TRUE;
  bfd_boolean is_full_prop_section;
  size_t last_zfill_target_offset = 0;
  asection *last_zfill_target_sec = NULL;
  bfd_size_type sec_size;

  sec_size = bfd_get_section_limit (abfd, sec);
  internal_relocs = retrieve_internal_relocs (abfd, sec, 
					      link_info->keep_memory);
  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec_size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  is_full_prop_section =
    ((strcmp (sec->name, XTENSA_PROP_SEC_NAME) == 0)
     || (strncmp (sec->name, ".gnu.linkonce.prop.",
		  sizeof ".gnu.linkonce.prop." - 1) == 0));

  if (internal_relocs)
    {
      for (i = 0; i < sec->reloc_count; i++)
	{
	  Elf_Internal_Rela *irel;
	  xtensa_relax_info *target_relax_info;
	  unsigned r_type;
	  asection *target_sec;
	  literal_value val;
	  bfd_byte *size_p, *flags_p;

	  /* Locally change the source address.
	     Translate the target to the new target address.
	     If it points to this section and has been removed, MOVE IT.
	     Also, don't forget to modify the associated SIZE at
	     (offset + 4).  */

	  irel = &internal_relocs[i];
	  r_type = ELF32_R_TYPE (irel->r_info);
	  if (r_type == R_XTENSA_NONE)
	    continue;

	  /* Find the literal value.  */
	  r_reloc_init (&val.r_rel, abfd, irel, contents, sec_size);
	  size_p = &contents[irel->r_offset + 4];
	  flags_p = NULL;
	  if (is_full_prop_section)
	    {
	      flags_p = &contents[irel->r_offset + 8];
	      BFD_ASSERT (irel->r_offset + 12 <= sec_size);
	    }
	  else
	    BFD_ASSERT (irel->r_offset + 8 <= sec_size);

	  target_sec = r_reloc_get_section (&val.r_rel);
	  target_relax_info = get_xtensa_relax_info (target_sec);

	  if (target_relax_info
	      && (target_relax_info->is_relaxable_literal_section
		  || target_relax_info->is_relaxable_asm_section ))
	    {
	      /* Translate the relocation's destination.  */
	      bfd_vma new_offset, new_end_offset;
	      long old_size, new_size;

	      new_offset = offset_with_removed_text
		(&target_relax_info->action_list, val.r_rel.target_offset);

	      /* Assert that we are not out of bounds.  */
	      old_size = bfd_get_32 (abfd, size_p);

	      if (old_size == 0)
		{
		  /* Only the first zero-sized unreachable entry is
		     allowed to expand.  In this case the new offset
		     should be the offset before the fill and the new
		     size is the expansion size.  For other zero-sized
		     entries the resulting size should be zero with an
		     offset before or after the fill address depending
		     on whether the expanding unreachable entry
		     preceeds it.  */
		  if (last_zfill_target_sec
		      && last_zfill_target_sec == target_sec
		      && last_zfill_target_offset == val.r_rel.target_offset)
		    new_end_offset = new_offset;
		  else
		    {
		      new_end_offset = new_offset;
		      new_offset = offset_with_removed_text_before_fill
			(&target_relax_info->action_list,
			 val.r_rel.target_offset);

		      /* If it is not unreachable and we have not yet
			 seen an unreachable at this address, place it
			 before the fill address.  */
		      if (!flags_p
			  || (bfd_get_32 (abfd, flags_p)
			      & XTENSA_PROP_UNREACHABLE) == 0)
			new_end_offset = new_offset;
		      else
			{
			  last_zfill_target_sec = target_sec;
			  last_zfill_target_offset = val.r_rel.target_offset;
			}
		    }
		}
	      else
		{
		  new_end_offset = offset_with_removed_text_before_fill
		    (&target_relax_info->action_list,
		     val.r_rel.target_offset + old_size);
		}

	      new_size = new_end_offset - new_offset;

	      if (new_size != old_size)
		{
		  bfd_put_32 (abfd, new_size, size_p);
		  pin_contents (sec, contents);
		}

	      if (new_offset != val.r_rel.target_offset)
		{
		  bfd_vma diff = new_offset - val.r_rel.target_offset;
		  irel->r_addend += diff;
		  pin_internal_relocs (sec, internal_relocs);
		}
	    }
	}
    }

  /* Combine adjacent property table entries.  This is also done in
     finish_dynamic_sections() but at that point it's too late to
     reclaim the space in the output section, so we do this twice.  */

  if (internal_relocs && (!link_info->relocatable
			  || strcmp (sec->name, XTENSA_LIT_SEC_NAME) == 0))
    {
      Elf_Internal_Rela *last_irel = NULL;
      int removed_bytes = 0;
      bfd_vma offset, last_irel_offset;
      bfd_vma section_size;
      bfd_size_type entry_size;
      flagword predef_flags;

      if (is_full_prop_section)
	entry_size = 12;
      else
	entry_size = 8;

      predef_flags = xtensa_get_property_predef_flags (sec);

      /* Walk over memory and irels at the same time.
         This REQUIRES that the internal_relocs be sorted by offset.  */
      qsort (internal_relocs, sec->reloc_count, sizeof (Elf_Internal_Rela),
	     internal_reloc_compare);
      nexti = 0; /* Index into internal_relocs.  */

      pin_internal_relocs (sec, internal_relocs);
      pin_contents (sec, contents);

      last_irel_offset = (bfd_vma) -1;
      section_size = sec->size;
      BFD_ASSERT (section_size % entry_size == 0);

      for (offset = 0; offset < section_size; offset += entry_size)
	{
	  Elf_Internal_Rela *irel, *next_irel;
	  bfd_vma bytes_to_remove, size, actual_offset;
	  bfd_boolean remove_this_irel;
	  flagword flags;

	  irel = NULL;
	  next_irel = NULL;

	  /* Find the next two relocations (if there are that many left),
	     skipping over any R_XTENSA_NONE relocs.  On entry, "nexti" is
	     the starting reloc index.  After these two loops, "i"
	     is the index of the first non-NONE reloc past that starting
	     index, and "nexti" is the index for the next non-NONE reloc
	     after "i".  */

	  for (i = nexti; i < sec->reloc_count; i++)
	    {
	      if (ELF32_R_TYPE (internal_relocs[i].r_info) != R_XTENSA_NONE)
		{
		  irel = &internal_relocs[i];
		  break;
		}
	      internal_relocs[i].r_offset -= removed_bytes;
	    }

	  for (nexti = i + 1; nexti < sec->reloc_count; nexti++)
	    {
	      if (ELF32_R_TYPE (internal_relocs[nexti].r_info)
		  != R_XTENSA_NONE)
		{
		  next_irel = &internal_relocs[nexti];
		  break;
		}
	      internal_relocs[nexti].r_offset -= removed_bytes;
	    }

	  remove_this_irel = FALSE;
	  bytes_to_remove = 0;
	  actual_offset = offset - removed_bytes;
	  size = bfd_get_32 (abfd, &contents[actual_offset + 4]);

	  if (is_full_prop_section) 
	    flags = bfd_get_32 (abfd, &contents[actual_offset + 8]);
	  else
	    flags = predef_flags;

	  /* Check that the irels are sorted by offset,
	     with only one per address.  */
	  BFD_ASSERT (!irel || (int) irel->r_offset > (int) last_irel_offset); 
	  BFD_ASSERT (!next_irel || next_irel->r_offset > irel->r_offset);

	  /* Make sure there aren't relocs on the size or flag fields.  */
	  if ((irel && irel->r_offset == offset + 4)
	      || (is_full_prop_section 
		  && irel && irel->r_offset == offset + 8))
	    {
	      irel->r_offset -= removed_bytes;
	      last_irel_offset = irel->r_offset;
	    }
	  else if (next_irel && (next_irel->r_offset == offset + 4
				 || (is_full_prop_section 
				     && next_irel->r_offset == offset + 8)))
	    {
	      nexti += 1;
	      irel->r_offset -= removed_bytes;
	      next_irel->r_offset -= removed_bytes;
	      last_irel_offset = next_irel->r_offset;
	    }
	  else if (size == 0 && (flags & XTENSA_PROP_ALIGN) == 0
		   && (flags & XTENSA_PROP_UNREACHABLE) == 0)
	    {
	      /* Always remove entries with zero size and no alignment.  */
	      bytes_to_remove = entry_size;
	      if (irel && irel->r_offset == offset)
		{
		  remove_this_irel = TRUE;

		  irel->r_offset -= removed_bytes;
		  last_irel_offset = irel->r_offset;
		}
	    }
	  else if (irel && irel->r_offset == offset)
	    {
	      if (ELF32_R_TYPE (irel->r_info) == R_XTENSA_32)
		{
		  if (last_irel)
		    {
		      flagword old_flags;
		      bfd_vma old_size =
			bfd_get_32 (abfd, &contents[last_irel->r_offset + 4]);
		      bfd_vma old_address =
			(last_irel->r_addend
			 + bfd_get_32 (abfd, &contents[last_irel->r_offset]));
		      bfd_vma new_address =
			(irel->r_addend
			 + bfd_get_32 (abfd, &contents[actual_offset]));
		      if (is_full_prop_section) 
			old_flags = bfd_get_32
			  (abfd, &contents[last_irel->r_offset + 8]);
		      else
			old_flags = predef_flags;

		      if ((ELF32_R_SYM (irel->r_info)
			   == ELF32_R_SYM (last_irel->r_info))
			  && old_address + old_size == new_address
			  && old_flags == flags
			  && (old_flags & XTENSA_PROP_INSN_BRANCH_TARGET) == 0
			  && (old_flags & XTENSA_PROP_INSN_LOOP_TARGET) == 0)
			{
			  /* Fix the old size.  */
			  bfd_put_32 (abfd, old_size + size,
				      &contents[last_irel->r_offset + 4]);
			  bytes_to_remove = entry_size;
			  remove_this_irel = TRUE;
			}
		      else
			last_irel = irel;
		    }
		  else
		    last_irel = irel;
		}

	      irel->r_offset -= removed_bytes;
	      last_irel_offset = irel->r_offset;
	    }

	  if (remove_this_irel)
	    {
	      irel->r_info = ELF32_R_INFO (0, R_XTENSA_NONE);
	      irel->r_offset -= bytes_to_remove;
	    }

	  if (bytes_to_remove != 0)
	    {
	      removed_bytes += bytes_to_remove;
	      if (offset + bytes_to_remove < section_size)
		memmove (&contents[actual_offset],
			 &contents[actual_offset + bytes_to_remove],
			 section_size - offset - bytes_to_remove);
	    }
	}

      if (removed_bytes)
	{
	  /* Clear the removed bytes.  */
	  memset (&contents[section_size - removed_bytes], 0, removed_bytes);

	  sec->size = section_size - removed_bytes;

	  if (xtensa_is_littable_section (sec))
	    {
	      bfd *dynobj = elf_hash_table (link_info)->dynobj;
	      if (dynobj)
		{
		  asection *sgotloc =
		    bfd_get_section_by_name (dynobj, ".got.loc");
		  if (sgotloc)
		    sgotloc->size -= removed_bytes;
		}
	    }
	}
    }

 error_return:
  release_internal_relocs (sec, internal_relocs);
  release_contents (sec, contents);
  return ok;
}


/* Third relaxation pass.  */

/* Change symbol values to account for removed literals.  */

bfd_boolean
relax_section_symbols (bfd *abfd, asection *sec)
{
  xtensa_relax_info *relax_info;
  unsigned int sec_shndx;
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Sym *isymbuf;
  unsigned i, num_syms, num_locals;

  relax_info = get_xtensa_relax_info (sec);
  BFD_ASSERT (relax_info);

  if (!relax_info->is_relaxable_literal_section
      && !relax_info->is_relaxable_asm_section)
    return TRUE;

  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  isymbuf = retrieve_local_syms (abfd);

  num_syms = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
  num_locals = symtab_hdr->sh_info;

  /* Adjust the local symbols defined in this section.  */
  for (i = 0; i < num_locals; i++)
    {
      Elf_Internal_Sym *isym = &isymbuf[i];

      if (isym->st_shndx == sec_shndx)
	{
	  bfd_vma new_address = offset_with_removed_text
	    (&relax_info->action_list, isym->st_value);
	  bfd_vma new_size = isym->st_size;

	  if (ELF32_ST_TYPE (isym->st_info) == STT_FUNC)
	    {
	      bfd_vma new_end = offset_with_removed_text
		(&relax_info->action_list, isym->st_value + isym->st_size);
	      new_size = new_end - new_address;
	    }

	  isym->st_value = new_address;
	  isym->st_size = new_size;
	}
    }

  /* Now adjust the global symbols defined in this section.  */
  for (i = 0; i < (num_syms - num_locals); i++)
    {
      struct elf_link_hash_entry *sym_hash;

      sym_hash = elf_sym_hashes (abfd)[i];

      if (sym_hash->root.type == bfd_link_hash_warning)
	sym_hash = (struct elf_link_hash_entry *) sym_hash->root.u.i.link;

      if ((sym_hash->root.type == bfd_link_hash_defined
	   || sym_hash->root.type == bfd_link_hash_defweak)
	  && sym_hash->root.u.def.section == sec)
	{
	  bfd_vma new_address = offset_with_removed_text
	    (&relax_info->action_list, sym_hash->root.u.def.value);
	  bfd_vma new_size = sym_hash->size;

	  if (sym_hash->type == STT_FUNC)
	    {
	      bfd_vma new_end = offset_with_removed_text
		(&relax_info->action_list,
		 sym_hash->root.u.def.value + sym_hash->size);
	      new_size = new_end - new_address;
	    }

	  sym_hash->root.u.def.value = new_address;
	  sym_hash->size = new_size;
	}
    }

  return TRUE;
}


/* "Fix" handling functions, called while performing relocations.  */

static bfd_boolean
do_fix_for_relocatable_link (Elf_Internal_Rela *rel,
			     bfd *input_bfd,
			     asection *input_section,
			     bfd_byte *contents)
{
  r_reloc r_rel;
  asection *sec, *old_sec;
  bfd_vma old_offset;
  int r_type = ELF32_R_TYPE (rel->r_info);
  reloc_bfd_fix *fix;

  if (r_type == R_XTENSA_NONE)
    return TRUE;

  fix = get_bfd_fix (input_section, rel->r_offset, r_type);
  if (!fix)
    return TRUE;

  r_reloc_init (&r_rel, input_bfd, rel, contents,
		bfd_get_section_limit (input_bfd, input_section));
  old_sec = r_reloc_get_section (&r_rel);
  old_offset = r_rel.target_offset;

  if (!old_sec || !r_reloc_is_defined (&r_rel))
    {
      if (r_type != R_XTENSA_ASM_EXPAND)
	{
	  (*_bfd_error_handler)
	    (_("%B(%A+0x%lx): unexpected fix for %s relocation"),
	     input_bfd, input_section, rel->r_offset,
	     elf_howto_table[r_type].name);
	  return FALSE;
	}
      /* Leave it be.  Resolution will happen in a later stage.  */
    }
  else
    {
      sec = fix->target_sec;
      rel->r_addend += ((sec->output_offset + fix->target_offset)
			- (old_sec->output_offset + old_offset));
    }
  return TRUE;
}


static void
do_fix_for_final_link (Elf_Internal_Rela *rel,
		       bfd *input_bfd,
		       asection *input_section,
		       bfd_byte *contents,
		       bfd_vma *relocationp)
{
  asection *sec;
  int r_type = ELF32_R_TYPE (rel->r_info);
  reloc_bfd_fix *fix;
  bfd_vma fixup_diff;

  if (r_type == R_XTENSA_NONE)
    return;

  fix = get_bfd_fix (input_section, rel->r_offset, r_type);
  if (!fix)
    return;

  sec = fix->target_sec;

  fixup_diff = rel->r_addend;
  if (elf_howto_table[fix->src_type].partial_inplace)
    {
      bfd_vma inplace_val;
      BFD_ASSERT (fix->src_offset
		  < bfd_get_section_limit (input_bfd, input_section));
      inplace_val = bfd_get_32 (input_bfd, &contents[fix->src_offset]);
      fixup_diff += inplace_val;
    }

  *relocationp = (sec->output_section->vma
		  + sec->output_offset
		  + fix->target_offset - fixup_diff);
}


/* Miscellaneous utility functions....  */

static asection *
elf_xtensa_get_plt_section (bfd *dynobj, int chunk)
{
  char plt_name[10];

  if (chunk == 0)
    return bfd_get_section_by_name (dynobj, ".plt");

  sprintf (plt_name, ".plt.%u", chunk);
  return bfd_get_section_by_name (dynobj, plt_name);
}


static asection *
elf_xtensa_get_gotplt_section (bfd *dynobj, int chunk)
{
  char got_name[14];

  if (chunk == 0)
    return bfd_get_section_by_name (dynobj, ".got.plt");

  sprintf (got_name, ".got.plt.%u", chunk);
  return bfd_get_section_by_name (dynobj, got_name);
}


/* Get the input section for a given symbol index.
   If the symbol is:
   . a section symbol, return the section;
   . a common symbol, return the common section;
   . an undefined symbol, return the undefined section;
   . an indirect symbol, follow the links;
   . an absolute value, return the absolute section.  */

static asection *
get_elf_r_symndx_section (bfd *abfd, unsigned long r_symndx)
{
  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  asection *target_sec = NULL;
  if (r_symndx < symtab_hdr->sh_info)
    {
      Elf_Internal_Sym *isymbuf;
      unsigned int section_index;

      isymbuf = retrieve_local_syms (abfd);
      section_index = isymbuf[r_symndx].st_shndx;

      if (section_index == SHN_UNDEF)
	target_sec = bfd_und_section_ptr;
      else if (section_index > 0 && section_index < SHN_LORESERVE)
	target_sec = bfd_section_from_elf_index (abfd, section_index);
      else if (section_index == SHN_ABS)
	target_sec = bfd_abs_section_ptr;
      else if (section_index == SHN_COMMON)
	target_sec = bfd_com_section_ptr;
      else
	/* Who knows?  */
	target_sec = NULL;
    }
  else
    {
      unsigned long indx = r_symndx - symtab_hdr->sh_info;
      struct elf_link_hash_entry *h = elf_sym_hashes (abfd)[indx];

      while (h->root.type == bfd_link_hash_indirect
             || h->root.type == bfd_link_hash_warning)
        h = (struct elf_link_hash_entry *) h->root.u.i.link;

      switch (h->root.type)
	{
	case bfd_link_hash_defined:
	case  bfd_link_hash_defweak:
	  target_sec = h->root.u.def.section;
	  break;
	case bfd_link_hash_common:
	  target_sec = bfd_com_section_ptr;
	  break;
	case bfd_link_hash_undefined:
	case bfd_link_hash_undefweak:
	  target_sec = bfd_und_section_ptr;
	  break;
	default: /* New indirect warning.  */
	  target_sec = bfd_und_section_ptr;
	  break;
	}
    }
  return target_sec;
}


static struct elf_link_hash_entry *
get_elf_r_symndx_hash_entry (bfd *abfd, unsigned long r_symndx)
{
  unsigned long indx;
  struct elf_link_hash_entry *h;
  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;

  if (r_symndx < symtab_hdr->sh_info)
    return NULL;

  indx = r_symndx - symtab_hdr->sh_info;
  h = elf_sym_hashes (abfd)[indx];
  while (h->root.type == bfd_link_hash_indirect
	 || h->root.type == bfd_link_hash_warning)
    h = (struct elf_link_hash_entry *) h->root.u.i.link;
  return h;
}


/* Get the section-relative offset for a symbol number.  */

static bfd_vma
get_elf_r_symndx_offset (bfd *abfd, unsigned long r_symndx)
{
  Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  bfd_vma offset = 0;

  if (r_symndx < symtab_hdr->sh_info)
    {
      Elf_Internal_Sym *isymbuf;
      isymbuf = retrieve_local_syms (abfd);
      offset = isymbuf[r_symndx].st_value;
    }
  else
    {
      unsigned long indx = r_symndx - symtab_hdr->sh_info;
      struct elf_link_hash_entry *h =
	elf_sym_hashes (abfd)[indx];

      while (h->root.type == bfd_link_hash_indirect
             || h->root.type == bfd_link_hash_warning)
	h = (struct elf_link_hash_entry *) h->root.u.i.link;
      if (h->root.type == bfd_link_hash_defined
          || h->root.type == bfd_link_hash_defweak)
	offset = h->root.u.def.value;
    }
  return offset;
}


static bfd_boolean
is_reloc_sym_weak (bfd *abfd, Elf_Internal_Rela *rel)
{
  unsigned long r_symndx = ELF32_R_SYM (rel->r_info);
  struct elf_link_hash_entry *h;

  h = get_elf_r_symndx_hash_entry (abfd, r_symndx);
  if (h && h->root.type == bfd_link_hash_defweak)
    return TRUE;
  return FALSE;
}


static bfd_boolean
pcrel_reloc_fits (xtensa_opcode opc,
		  int opnd,
		  bfd_vma self_address,
		  bfd_vma dest_address)
{
  xtensa_isa isa = xtensa_default_isa;
  uint32 valp = dest_address;
  if (xtensa_operand_do_reloc (isa, opc, opnd, &valp, self_address)
      || xtensa_operand_encode (isa, opc, opnd, &valp))
    return FALSE;
  return TRUE;
}


static int linkonce_len = sizeof (".gnu.linkonce.") - 1;
static int insn_sec_len = sizeof (XTENSA_INSN_SEC_NAME) - 1;
static int lit_sec_len = sizeof (XTENSA_LIT_SEC_NAME) - 1;
static int prop_sec_len = sizeof (XTENSA_PROP_SEC_NAME) - 1;


static bfd_boolean 
xtensa_is_property_section (asection *sec)
{
  if (strncmp (XTENSA_INSN_SEC_NAME, sec->name, insn_sec_len) == 0
      || strncmp (XTENSA_LIT_SEC_NAME, sec->name, lit_sec_len) == 0
      || strncmp (XTENSA_PROP_SEC_NAME, sec->name, prop_sec_len) == 0)
    return TRUE;

  if (strncmp (".gnu.linkonce.", sec->name, linkonce_len) == 0
      && (strncmp (&sec->name[linkonce_len], "x.", 2) == 0
	  || strncmp (&sec->name[linkonce_len], "p.", 2) == 0
	  || strncmp (&sec->name[linkonce_len], "prop.", 5) == 0))
    return TRUE;

  return FALSE;
}


static bfd_boolean 
xtensa_is_littable_section (asection *sec)
{
  if (strncmp (XTENSA_LIT_SEC_NAME, sec->name, lit_sec_len) == 0)
    return TRUE;

  if (strncmp (".gnu.linkonce.", sec->name, linkonce_len) == 0
      && sec->name[linkonce_len] == 'p'
      && sec->name[linkonce_len + 1] == '.')
    return TRUE;

  return FALSE;
}


static int
internal_reloc_compare (const void *ap, const void *bp)
{
  const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap;
  const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp;

  if (a->r_offset != b->r_offset)
    return (a->r_offset - b->r_offset);

  /* We don't need to sort on these criteria for correctness,
     but enforcing a more strict ordering prevents unstable qsort
     from behaving differently with different implementations.
     Without the code below we get correct but different results
     on Solaris 2.7 and 2.8.  We would like to always produce the
     same results no matter the host.  */

  if (a->r_info != b->r_info)
    return (a->r_info - b->r_info);

  return (a->r_addend - b->r_addend);
}


static int
internal_reloc_matches (const void *ap, const void *bp)
{
  const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap;
  const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp;

  /* Check if one entry overlaps with the other; this shouldn't happen
     except when searching for a match.  */
  return (a->r_offset - b->r_offset);
}


char *
xtensa_get_property_section_name (asection *sec, const char *base_name)
{
  if (strncmp (sec->name, ".gnu.linkonce.", linkonce_len) == 0)
    {
      char *prop_sec_name;
      const char *suffix;
      char *linkonce_kind = 0;

      if (strcmp (base_name, XTENSA_INSN_SEC_NAME) == 0) 
	linkonce_kind = "x";
      else if (strcmp (base_name, XTENSA_LIT_SEC_NAME) == 0) 
	linkonce_kind = "p";
      else if (strcmp (base_name, XTENSA_PROP_SEC_NAME) == 0)
	linkonce_kind = "prop.";
      else
	abort ();

      prop_sec_name = (char *) bfd_malloc (strlen (sec->name)
					   + strlen (linkonce_kind) + 1);
      memcpy (prop_sec_name, ".gnu.linkonce.", linkonce_len);
      strcpy (prop_sec_name + linkonce_len, linkonce_kind);

      suffix = sec->name + linkonce_len;
      /* For backward compatibility, replace "t." instead of inserting
         the new linkonce_kind (but not for "prop" sections).  */
      if (strncmp (suffix, "t.", 2) == 0 && linkonce_kind[1] == '.')
        suffix += 2;
      strcat (prop_sec_name + linkonce_len, suffix);

      return prop_sec_name;
    }

  return strdup (base_name);
}


flagword
xtensa_get_property_predef_flags (asection *sec)
{
  if (strcmp (sec->name, XTENSA_INSN_SEC_NAME) == 0
      || strncmp (sec->name, ".gnu.linkonce.x.",
		  sizeof ".gnu.linkonce.x." - 1) == 0)
    return (XTENSA_PROP_INSN
	    | XTENSA_PROP_INSN_NO_TRANSFORM
	    | XTENSA_PROP_INSN_NO_REORDER);

  if (xtensa_is_littable_section (sec))
    return (XTENSA_PROP_LITERAL
	    | XTENSA_PROP_INSN_NO_TRANSFORM
	    | XTENSA_PROP_INSN_NO_REORDER);

  return 0;
}


/* Other functions called directly by the linker.  */

bfd_boolean
xtensa_callback_required_dependence (bfd *abfd,
				     asection *sec,
				     struct bfd_link_info *link_info,
				     deps_callback_t callback,
				     void *closure)
{
  Elf_Internal_Rela *internal_relocs;
  bfd_byte *contents;
  unsigned i;
  bfd_boolean ok = TRUE;
  bfd_size_type sec_size;

  sec_size = bfd_get_section_limit (abfd, sec);

  /* ".plt*" sections have no explicit relocations but they contain L32R
     instructions that reference the corresponding ".got.plt*" sections.  */
  if ((sec->flags & SEC_LINKER_CREATED) != 0
      && strncmp (sec->name, ".plt", 4) == 0)
    {
      asection *sgotplt;

      /* Find the corresponding ".got.plt*" section.  */
      if (sec->name[4] == '\0')
	sgotplt = bfd_get_section_by_name (sec->owner, ".got.plt");
      else
	{
	  char got_name[14];
	  int chunk = 0;

	  BFD_ASSERT (sec->name[4] == '.');
	  chunk = strtol (&sec->name[5], NULL, 10);

	  sprintf (got_name, ".got.plt.%u", chunk);
	  sgotplt = bfd_get_section_by_name (sec->owner, got_name);
	}
      BFD_ASSERT (sgotplt);

      /* Assume worst-case offsets: L32R at the very end of the ".plt"
	 section referencing a literal at the very beginning of
	 ".got.plt".  This is very close to the real dependence, anyway.  */
      (*callback) (sec, sec_size, sgotplt, 0, closure);
    }

  internal_relocs = retrieve_internal_relocs (abfd, sec, 
					      link_info->keep_memory);
  if (internal_relocs == NULL
      || sec->reloc_count == 0)
    return ok;

  /* Cache the contents for the duration of this scan.  */
  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec_size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  if (!xtensa_default_isa)
    xtensa_default_isa = xtensa_isa_init (0, 0);

  for (i = 0; i < sec->reloc_count; i++)
    {
      Elf_Internal_Rela *irel = &internal_relocs[i];
      if (is_l32r_relocation (abfd, sec, contents, irel))
	{
	  r_reloc l32r_rel;
	  asection *target_sec;
	  bfd_vma target_offset;

	  r_reloc_init (&l32r_rel, abfd, irel, contents, sec_size);
	  target_sec = NULL;
	  target_offset = 0;
	  /* L32Rs must be local to the input file.  */
	  if (r_reloc_is_defined (&l32r_rel))
	    {
	      target_sec = r_reloc_get_section (&l32r_rel);
	      target_offset = l32r_rel.target_offset;
	    }
	  (*callback) (sec, irel->r_offset, target_sec, target_offset,
		       closure);
	}
    }

 error_return:
  release_internal_relocs (sec, internal_relocs);
  release_contents (sec, contents);
  return ok;
}

/* The default literal sections should always be marked as "code" (i.e.,
   SHF_EXECINSTR).  This is particularly important for the Linux kernel
   module loader so that the literals are not placed after the text.  */
static struct bfd_elf_special_section const elf_xtensa_special_sections[]=
{
  { ".literal",       8, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
  { ".init.literal", 13, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
  { ".fini.literal", 13, 0, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR },
  { NULL,             0, 0, 0,            0 }
};


#ifndef ELF_ARCH
#define TARGET_LITTLE_SYM		bfd_elf32_xtensa_le_vec
#define TARGET_LITTLE_NAME		"elf32-xtensa-le"
#define TARGET_BIG_SYM			bfd_elf32_xtensa_be_vec
#define TARGET_BIG_NAME			"elf32-xtensa-be"
#define ELF_ARCH			bfd_arch_xtensa

/* The new EM_XTENSA value will be recognized beginning in the Xtensa T1040
   release. However, we still have to generate files with the EM_XTENSA_OLD
   value so that pre-T1040 tools can read the files.  As soon as we stop
   caring about pre-T1040 tools, the following two values should be
   swapped. At the same time, any other code that uses EM_XTENSA_OLD
   should be changed to use EM_XTENSA.  */
#define ELF_MACHINE_CODE		EM_XTENSA_OLD
#define ELF_MACHINE_ALT1		EM_XTENSA

#if XCHAL_HAVE_MMU
#define ELF_MAXPAGESIZE			(1 << XCHAL_MMU_MIN_PTE_PAGE_SIZE)
#else /* !XCHAL_HAVE_MMU */
#define ELF_MAXPAGESIZE			1
#endif /* !XCHAL_HAVE_MMU */
#endif /* ELF_ARCH */

#define elf_backend_can_gc_sections	1
#define elf_backend_can_refcount	1
#define elf_backend_plt_readonly	1
#define elf_backend_got_header_size	4
#define elf_backend_want_dynbss		0
#define elf_backend_want_got_plt	1

#define elf_info_to_howto		     elf_xtensa_info_to_howto_rela

#define bfd_elf32_bfd_merge_private_bfd_data elf_xtensa_merge_private_bfd_data
#define bfd_elf32_new_section_hook	     elf_xtensa_new_section_hook
#define bfd_elf32_bfd_print_private_bfd_data elf_xtensa_print_private_bfd_data
#define bfd_elf32_bfd_relax_section	     elf_xtensa_relax_section
#define bfd_elf32_bfd_reloc_type_lookup	     elf_xtensa_reloc_type_lookup
#define bfd_elf32_bfd_set_private_flags	     elf_xtensa_set_private_flags

#define elf_backend_adjust_dynamic_symbol    elf_xtensa_adjust_dynamic_symbol
#define elf_backend_check_relocs	     elf_xtensa_check_relocs
#define elf_backend_create_dynamic_sections  elf_xtensa_create_dynamic_sections
#define elf_backend_discard_info	     elf_xtensa_discard_info
#define elf_backend_ignore_discarded_relocs  elf_xtensa_ignore_discarded_relocs
#define elf_backend_final_write_processing   elf_xtensa_final_write_processing
#define elf_backend_finish_dynamic_sections  elf_xtensa_finish_dynamic_sections
#define elf_backend_finish_dynamic_symbol    elf_xtensa_finish_dynamic_symbol
#define elf_backend_gc_mark_hook	     elf_xtensa_gc_mark_hook
#define elf_backend_gc_sweep_hook	     elf_xtensa_gc_sweep_hook
#define elf_backend_grok_prstatus	     elf_xtensa_grok_prstatus
#define elf_backend_grok_psinfo		     elf_xtensa_grok_psinfo
#define elf_backend_hide_symbol		     elf_xtensa_hide_symbol
#define elf_backend_modify_segment_map	     elf_xtensa_modify_segment_map
#define elf_backend_object_p		     elf_xtensa_object_p
#define elf_backend_reloc_type_class	     elf_xtensa_reloc_type_class
#define elf_backend_relocate_section	     elf_xtensa_relocate_section
#define elf_backend_size_dynamic_sections    elf_xtensa_size_dynamic_sections
#define elf_backend_special_sections	     elf_xtensa_special_sections

#include "elf32-target.h"
