/* Xtensa-specific support for 32-bit ELF.
   Copyright 2003 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"

/* Main interface functions.  */
static void elf_xtensa_info_to_howto_rela
  PARAMS ((bfd *, arelent *, Elf_Internal_Rela *));
static reloc_howto_type *elf_xtensa_reloc_type_lookup
  PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
extern int xtensa_read_table_entries
  PARAMS ((bfd *, asection *, property_table_entry **, const char *));
static bfd_boolean elf_xtensa_check_relocs
  PARAMS ((bfd *, struct bfd_link_info *, asection *,
	   const Elf_Internal_Rela *));
static void elf_xtensa_hide_symbol
  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
static void elf_xtensa_copy_indirect_symbol
  PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
	   struct elf_link_hash_entry *));
static asection *elf_xtensa_gc_mark_hook
  PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,
	   struct elf_link_hash_entry *, Elf_Internal_Sym *));
static bfd_boolean elf_xtensa_gc_sweep_hook
  PARAMS ((bfd *, struct bfd_link_info *, asection *,
	   const Elf_Internal_Rela *));
static bfd_boolean elf_xtensa_create_dynamic_sections
  PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean elf_xtensa_adjust_dynamic_symbol
  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static bfd_boolean elf_xtensa_size_dynamic_sections
  PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean elf_xtensa_modify_segment_map
  PARAMS ((bfd *));
static bfd_boolean elf_xtensa_relocate_section
  PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
	   Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
static bfd_boolean elf_xtensa_relax_section
  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *again));
static bfd_boolean elf_xtensa_finish_dynamic_symbol
  PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
	   Elf_Internal_Sym *));
static bfd_boolean elf_xtensa_finish_dynamic_sections
  PARAMS ((bfd *, struct bfd_link_info *));
static bfd_boolean elf_xtensa_merge_private_bfd_data
  PARAMS ((bfd *, bfd *));
static bfd_boolean elf_xtensa_set_private_flags
  PARAMS ((bfd *, flagword));
extern flagword elf_xtensa_get_private_bfd_flags
  PARAMS ((bfd *));
static bfd_boolean elf_xtensa_print_private_bfd_data
  PARAMS ((bfd *, PTR));
static bfd_boolean elf_xtensa_object_p
  PARAMS ((bfd *));
static void elf_xtensa_final_write_processing
  PARAMS ((bfd *, bfd_boolean));
static enum elf_reloc_type_class elf_xtensa_reloc_type_class
  PARAMS ((const Elf_Internal_Rela *));
static bfd_boolean elf_xtensa_discard_info
  PARAMS ((bfd *, struct elf_reloc_cookie *, struct bfd_link_info *));
static bfd_boolean elf_xtensa_ignore_discarded_relocs
  PARAMS ((asection *));
static bfd_boolean elf_xtensa_grok_prstatus
  PARAMS ((bfd *, Elf_Internal_Note *));
static bfd_boolean elf_xtensa_grok_psinfo
  PARAMS ((bfd *, Elf_Internal_Note *));
static bfd_boolean elf_xtensa_new_section_hook
  PARAMS ((bfd *, asection *));


/* Local helper functions.  */

static int property_table_compare
  PARAMS ((const PTR, const PTR));
static bfd_boolean elf_xtensa_in_literal_pool
  PARAMS ((property_table_entry *, int, bfd_vma));
static void elf_xtensa_make_sym_local
  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static bfd_boolean add_extra_plt_sections
  PARAMS ((bfd *, int));
static bfd_boolean elf_xtensa_fix_refcounts
  PARAMS ((struct elf_link_hash_entry *, PTR));
static bfd_boolean elf_xtensa_allocate_plt_size
  PARAMS ((struct elf_link_hash_entry *, PTR));
static bfd_boolean elf_xtensa_allocate_got_size
  PARAMS ((struct elf_link_hash_entry *, PTR));
static void elf_xtensa_allocate_local_got_size
  PARAMS ((struct bfd_link_info *, asection *));
static bfd_reloc_status_type elf_xtensa_do_reloc
  PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_vma, bfd_byte *,
	   bfd_vma, bfd_boolean, char **));
static char * vsprint_msg
  VPARAMS ((const char *, const char *, int, ...));
static char *build_encoding_error_message
  PARAMS ((xtensa_opcode, xtensa_encode_result));
static bfd_reloc_status_type bfd_elf_xtensa_reloc
  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
static void do_fix_for_relocateable_link
  PARAMS ((Elf_Internal_Rela *, bfd *, asection *));
static void do_fix_for_final_link
  PARAMS ((Elf_Internal_Rela *, asection *, bfd_vma *));
static bfd_boolean xtensa_elf_dynamic_symbol_p
  PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
static bfd_vma elf_xtensa_create_plt_entry
  PARAMS ((bfd *, bfd *, unsigned));
static int elf_xtensa_combine_prop_entries
  PARAMS ((bfd *, const char *));
static bfd_boolean elf_xtensa_discard_info_for_section
  PARAMS ((bfd *, struct elf_reloc_cookie *, struct bfd_link_info *,
	   asection *));

/* Local functions to handle Xtensa configurability.  */

static void init_call_opcodes
  PARAMS ((void));
static bfd_boolean is_indirect_call_opcode
  PARAMS ((xtensa_opcode));
static bfd_boolean is_direct_call_opcode
  PARAMS ((xtensa_opcode));
static bfd_boolean is_windowed_call_opcode
  PARAMS ((xtensa_opcode));
static xtensa_opcode get_l32r_opcode
  PARAMS ((void));
static bfd_vma l32r_offset
  PARAMS ((bfd_vma, bfd_vma));
static int get_relocation_opnd
  PARAMS ((Elf_Internal_Rela *));
static xtensa_opcode get_relocation_opcode
  PARAMS ((asection *, bfd_byte *, Elf_Internal_Rela *));
static bfd_boolean is_l32r_relocation
  PARAMS ((asection *, bfd_byte *, Elf_Internal_Rela *));

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

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

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

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

/* Miscellaneous utility functions.  */

static asection *elf_xtensa_get_plt_section
  PARAMS ((bfd *, int));
static asection *elf_xtensa_get_gotplt_section
  PARAMS ((bfd *, int));
static asection *get_elf_r_symndx_section
  PARAMS ((bfd *, unsigned long));
static struct elf_link_hash_entry *get_elf_r_symndx_hash_entry
  PARAMS ((bfd *, unsigned long));
static bfd_vma get_elf_r_symndx_offset
  PARAMS ((bfd *, unsigned long));
static bfd_boolean pcrel_reloc_fits
  PARAMS ((xtensa_operand, bfd_vma, bfd_vma));
static bfd_boolean xtensa_is_property_section
  PARAMS ((asection *));
static bfd_boolean is_literal_section
  PARAMS ((asection *));
static int internal_reloc_compare
  PARAMS ((const PTR, const PTR));
static bfd_boolean get_is_linkonce_section
  PARAMS ((bfd *, asection *));
extern char *xtensa_get_property_section_name
  PARAMS ((bfd *, asection *, const char *));

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

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


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 is this count is an overestimate, e.g., some
   relocations may be removed by GC.  */

static int plt_reloc_count = 0;


/* 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;


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)
};

#ifdef 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 (abfd, code)
     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_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:
      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 (abfd, cache_ptr, dst)
     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 int
property_table_compare (ap, bp)
     const PTR ap;
     const PTR 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; this shouldn't happen
     except when searching for a match.  */
  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 instruction table entries for the given
   section.  Sets TABLE_P and returns the number of entries.  On error,
   returns a negative value.  */

int
xtensa_read_table_entries (abfd, section, table_p, sec_name)
     bfd *abfd;
     asection *section;
     property_table_entry **table_p;
     const char *sec_name;
{
  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;

  table_section_name = 
    xtensa_get_property_section_name (abfd, section, sec_name);
  table_section = bfd_get_section_by_name (abfd, table_section_name);
  if (table_section != NULL)
    table_size = bfd_get_section_size_before_reloc (table_section);
  
  if (table_size == 0) 
    {
      *table_p = NULL;
      return 0;
    }

  num_records = table_size / sizeof (property_table_entry);
  table_data = retrieve_contents (abfd, table_section, TRUE);
  blocks = (property_table_entry *)
    bfd_malloc (num_records * sizeof (property_table_entry));
  block_count = 0;
  
  /* 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)
    {
      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);
	      blocks[block_count].address =
		(section->vma + 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);
	      block_count++;
	    }
	}
    }
  else
    {
      /* No relocations.  Presumably the file has been relocated
	 and the addresses are already in the table.  */
      bfd_vma off;

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

	  if (address >= section->vma
	      && address < ( section->vma + section->_raw_size))
	    {
	      blocks[block_count].address = address;
	      blocks[block_count].size =
		bfd_get_32 (abfd, table_data + off + 4);
	      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 bfd_boolean
elf_xtensa_in_literal_pool (lit_table, lit_table_size, addr)
     property_table_entry *lit_table;
     int lit_table_size;
     bfd_vma addr;
{
  property_table_entry entry;

  if (lit_table_size == 0)
    return FALSE;

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

  if (bsearch (&entry, lit_table, lit_table_size,
	       sizeof (property_table_entry), property_table_compare))
    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 (abfd, info, sec, 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;
  property_table_entry *lit_table;
  int ltblsize;

  if (info->relocateable)
    return TRUE;

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

  ltblsize = xtensa_read_table_entries (abfd, sec, &lit_table,
					XTENSA_LIT_SEC_NAME);
  if (ltblsize < 0)
    return FALSE;

  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) (_("%s: bad symbol index: %d"),
				 bfd_archive_filename (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 ((sec->flags & SEC_READONLY) != 0
		  && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
						  sec->vma + rel->r_offset))
		h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;

	      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 ((sec->flags & SEC_READONLY) != 0
		  && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
						  sec->vma + rel->r_offset))
		h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;

	      if (h->plt.refcount <= 0)
		{
		  h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
		  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;

	      /* If the relocation is not inside the GOT, the DF_TEXTREL
		 flag needs to be set.  */
	      if (info->shared
		  && (sec->flags & SEC_READONLY) != 0
		  && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
						  sec->vma + rel->r_offset))
		info->flags |= DF_TEXTREL;
	    }
	  break;

	case R_XTENSA_OP0:
	case R_XTENSA_OP1:
	case R_XTENSA_OP2:
	case R_XTENSA_ASM_EXPAND:
	case R_XTENSA_ASM_SIMPLIFY:
	  /* 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_elf32_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_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
	    return FALSE;
	  break;

	default:
	  break;
	}
    }

  free (lit_table);
  return TRUE;
}


static void
elf_xtensa_hide_symbol (info, h, force_local)
     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);
}


static void
elf_xtensa_copy_indirect_symbol (bed, dir, ind)
     struct elf_backend_data *bed;
     struct elf_link_hash_entry *dir, *ind;
{
  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);

  /* The standard function doesn't copy the NEEDS_PLT flag.  */
  dir->elf_link_hash_flags |=
    (ind->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT);
}


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

static asection *
elf_xtensa_gc_mark_hook (sec, info, rel, h, sym)
     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 != NULL)
    {
      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 (abfd, info, sec, relocs)
     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 (dynobj, info)
     bfd *dynobj;
     struct bfd_link_info *info;
{
  flagword 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;

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

  /* 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 ".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, flags)
      || ! bfd_set_section_alignment (dynobj, s, 2))
    return FALSE;

  return TRUE;
}


static bfd_boolean
add_extra_plt_sections (dynobj, count)
     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 (info, h)
     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->weakdef != NULL)
    {
      BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined
		  || h->weakdef->root.type == bfd_link_hash_defweak);
      h->root.u.def.section = h->weakdef->root.u.def.section;
      h->root.u.def.value = h->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 void
elf_xtensa_make_sym_local (info, h)
     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->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
      h->plt.refcount = 0;
      h->got.refcount = 0;
    }
}


static bfd_boolean
elf_xtensa_fix_refcounts (h, arg)
     struct elf_link_hash_entry *h;
     PTR 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 (info, h))
    elf_xtensa_make_sym_local (info, h);

  /* If the symbol has a relocation outside the GOT, set the
     DF_TEXTREL flag.  */
  if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) != 0)
    info->flags |= DF_TEXTREL;

  return TRUE;
}


static bfd_boolean
elf_xtensa_allocate_plt_size (h, arg)
     struct elf_link_hash_entry *h;
     PTR 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->_raw_size += (h->plt.refcount * sizeof (Elf32_External_Rela));

  return TRUE;
}


static bfd_boolean
elf_xtensa_allocate_got_size (h, arg)
     struct elf_link_hash_entry *h;
     PTR 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->_raw_size += (h->got.refcount * sizeof (Elf32_External_Rela));

  return TRUE;
}


static void
elf_xtensa_allocate_local_got_size (info, srelgot)
     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->_raw_size += (local_got_refcounts[j]
				   * sizeof (Elf32_External_Rela));
	}
    }
}


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

static bfd_boolean
elf_xtensa_size_dynamic_sections (output_bfd, info)
     bfd *output_bfd ATTRIBUTE_UNUSED;
     struct bfd_link_info *info;
{
  bfd *dynobj;
  asection *s, *srelplt, *splt, *sgotplt, *srelgot, *spltlittbl;
  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->shared)
	{
	  s = bfd_get_section_by_name (dynobj, ".interp");
	  if (s == NULL)
	    abort ();
	  s->_raw_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->_raw_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,
			      (PTR) 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,
			      (PTR) 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,
			      (PTR) 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->_raw_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->_raw_size = 4 * (chunk_entries + 2);
	      splt->_raw_size = PLT_ENTRY_SIZE * chunk_entries;
	      srelgot->_raw_size += 2 * sizeof (Elf32_External_Rela);
	      spltlittbl->_raw_size += 8;
	    }
	  else
	    {
	      sgotplt->_raw_size = 0;
	      splt->_raw_size = 0;
	    }
	}
    }

  /* 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->_raw_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)
	{
	  /* 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->_raw_size);
	  if (s->contents == NULL && s->_raw_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_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (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 ((info->flags & DF_TEXTREL) != 0)
	{
	  if (!add_dynamic_entry (DT_TEXTREL, 0))
	    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 (abfd)
     bfd *abfd;
{
  struct elf_segment_map **m_p;

  m_p = &elf_tdata (abfd)->segment_map;
  while (*m_p != NULL)
    {
      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 (howto, abfd, input_section, relocation,
		     contents, address, is_weak_undef, error_message)
     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_opcode opcode;
  xtensa_operand operand;
  xtensa_encode_result encode_result;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_insnbuf ibuff;
  bfd_vma self_address;
  int opnd;
  uint32 newval;

  switch (howto->type)
    {
    case R_XTENSA_NONE:
      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_section->_raw_size - address);
	  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_section->_raw_size);
	if (retval != bfd_reloc_ok)
	  return retval;

	/* The CALL needs to be relocated.  Continue below for that part.  */
	address += 3;
	howto = &elf_howto_table[(unsigned) R_XTENSA_OP0 ];
      }
      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;
    }

  /* Read the instruction into a buffer and decode the opcode.  */
  ibuff = xtensa_insnbuf_alloc (isa);
  xtensa_insnbuf_from_chars (isa, ibuff, contents + address);
  opcode = xtensa_decode_insn (isa, ibuff);

  /* Determine which operand is being relocated.  */
  if (opcode == XTENSA_UNDEFINED)
    {
      *error_message = "cannot decode instruction";
      return bfd_reloc_dangerous;
    }

  if (howto->type < R_XTENSA_OP0 || howto->type > R_XTENSA_OP2)
    {
      *error_message = "unexpected relocation";
      return bfd_reloc_dangerous;
    }

  opnd = howto->type - R_XTENSA_OP0;

  /* Calculate the PC address for this instruction.  */
  if (!howto->pc_relative)
    {
      *error_message = "expected PC-relative relocation";
      return bfd_reloc_dangerous;
    }

  self_address = (input_section->output_section->vma
		  + input_section->output_offset
		  + address);

  /* Apply the relocation.  */
  operand = xtensa_get_operand (isa, opcode, opnd);
  newval = xtensa_operand_do_reloc (operand, relocation, self_address);
  encode_result = xtensa_operand_encode (operand, &newval);
  xtensa_operand_set_field (operand, ibuff, newval);

  /* Write the modified instruction back out of the buffer.  */
  xtensa_insnbuf_to_chars (isa, ibuff, contents + address);
  free (ibuff);

  if (encode_result != xtensa_encode_result_ok)
    {
      char *message = build_encoding_error_message (opcode, encode_result);
      *error_message = message;
      return bfd_reloc_dangerous;
    }

  /* Final check for call.  */
  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;
	}
    }

  return bfd_reloc_ok;
}


static char *
vsprint_msg VPARAMS ((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 (opcode, encode_result)
     xtensa_opcode opcode;
     xtensa_encode_result encode_result;
{
  const char *opname = xtensa_opcode_name (xtensa_default_isa, opcode);
  const char *msg = NULL;

  switch (encode_result)
    {
    case xtensa_encode_result_ok:
      msg = "unexpected valid encoding";
      break;
    case xtensa_encode_result_align:
      msg = "misaligned encoding";
      break;
    case xtensa_encode_result_not_in_table:
      msg = "encoding not in lookup table";
      break;
    case xtensa_encode_result_too_low:
      msg = "encoding out of range: too low";
      break;
    case xtensa_encode_result_too_high:
      msg = "encoding out of range: too high";
      break;
    case xtensa_encode_result_not_ok:
    default:
      msg = "could not encode";
      break;
    }

  if (is_direct_call_opcode (opcode)
      && (encode_result == xtensa_encode_result_too_low
	  || encode_result == xtensa_encode_result_too_high))

    msg = "direct call out of range";

  else if (opcode == get_l32r_opcode ()) 
    {
      /* L32Rs have the strange interaction with encoding in that they
         have an unsigned immediate field, so libisa returns "too high"
         when the absolute value is out of range and never returns "too
         low", but I leave the "too low" message in case anything
         changes.  */
      if (encode_result == xtensa_encode_result_too_low)
	msg = "literal out of range";
      else if (encode_result == xtensa_encode_result_too_high)
	msg = "literal placed after use";
    }
  
  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 (abfd, reloc_entry, symbol, data, input_section,
		      output_bfd, error_message)
     bfd *abfd;
     arelent *reloc_entry;
     asymbol *symbol;
     PTR 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 relocateable
     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 != (bfd *) NULL
      && (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 > (input_section->_cooked_size
			      / bfd_octets_per_byte (abfd)))
    return bfd_reloc_outofrange;

  /* Work out which section the relocation is targetted 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 (dynobj, output_bfd, reloc_index)
      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;
}


static bfd_boolean
xtensa_elf_dynamic_symbol_p (info, h)
     struct bfd_link_info *info;
     struct elf_link_hash_entry *h;
{
  if (h == NULL)
    return FALSE;

  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->dynindx == -1)
    return FALSE;

  if (h->root.type == bfd_link_hash_undefweak
      || h->root.type == bfd_link_hash_defweak)
    return TRUE;

  switch (ELF_ST_VISIBILITY (h->other))
    {
    case STV_DEFAULT:
      break;
    case STV_HIDDEN:
    case STV_INTERNAL:
      return FALSE;
    case STV_PROTECTED:
      if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
        return FALSE;
      break;
    }

  if ((info->shared && !info->symbolic)
      || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
    return TRUE;

  return FALSE;
}


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

static bfd_boolean
elf_xtensa_relocate_section (output_bfd, info, input_bfd,
			     input_section, contents, relocs,
			     local_syms, local_sections)
     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;
  char *error_message = NULL;

  if (xtensa_default_isa == NULL)
    xtensa_isa_init ();

  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 != NULL)
    {
      srelgot = bfd_get_section_by_name (dynobj, ".rela.got");;
      srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
    }

  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->relocateable)
	{
	  /* This is a relocateable 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.  */
	      do_fix_for_relocateable_link (rel, input_bfd, input_section);
	      r_type = ELF32_R_TYPE (rel->r_info);
	    }

	  if (r_type == R_XTENSA_ASM_SIMPLIFY) 
	    {
	      /* Convert ASM_SIMPLIFY into the simpler relocation
		 so that they never escape a relaxing link.  */
	      contract_asm_expansion (contents, input_section->_raw_size, rel);
	      r_type = ELF32_R_TYPE (rel->r_info);
	    }

	  /* This is a relocateable 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 relocateable 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 relocateable 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
	{
	  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;

	  relocation = 0;
	  if (h->root.type == bfd_link_hash_defined
	      || h->root.type == bfd_link_hash_defweak)
	    {
	      sec = h->root.u.def.section;

	      if (sec->output_section == NULL)
		/* Set a flag that will be cleared later if we find a
		   relocation value for this symbol.  output_section
		   is typically NULL for symbols satisfied by a shared
		   library.  */
		unresolved_reloc = TRUE;
	      else
		relocation = (h->root.u.def.value
			      + sec->output_section->vma
			      + sec->output_offset);
	    }
	  else if (h->root.type == bfd_link_hash_undefweak)
	    is_weak_undef = TRUE;
	  else if (info->shared
		   && !info->no_undefined
		   && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
	    ;
	  else
	    {
	      if (! ((*info->callbacks->undefined_symbol)
		     (info, h->root.root.string, input_bfd,
		      input_section, rel->r_offset,
		      (!info->shared || info->no_undefined
		       || ELF_ST_VISIBILITY (h->other)))))
		return FALSE;
	      warned = TRUE;
	    }
	}

      if (relaxing_section)
	{
	  /* Check if this references a section in another input file.  */
	  do_fix_for_final_link (rel, input_section, &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_section->_raw_size
	  && ELF32_R_TYPE (rel->r_info) != R_XTENSA_NONE)
	{
	  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 (info, h);

	  if (dynamic_symbol && (r_type == R_XTENSA_OP0
				 || r_type == R_XTENSA_OP1
				 || r_type == R_XTENSA_OP2))
	    {
	      /* 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);

		  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->_cooked_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->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))
	(*_bfd_error_handler)
	  (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"),
	   bfd_archive_filename (input_bfd),
	   bfd_get_section_name (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);
	  BFD_ASSERT (error_message != (char *) NULL);

	  if (h != NULL)
	    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)
	    error_message = vsprint_msg (error_message, ": %s",
					 strlen (name), name);
	  if (!((*info->callbacks->reloc_dangerous)
		(info, error_message, input_bfd, input_section,
		 rel->r_offset)))
	    return FALSE;
	}
    }

  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 (output_bfd, info, h, sym)
     bfd *output_bfd ATTRIBUTE_UNUSED;
     struct bfd_link_info *info ATTRIBUTE_UNUSED;
     struct elf_link_hash_entry *h;
     Elf_Internal_Sym *sym;
{
  if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0
      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
    {
      /* 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 (output_bfd, secname)
     bfd *output_bfd;
     const char *secname;
{
  asection *sec;
  bfd_byte *contents;
  property_table_entry *table;
  bfd_size_type section_size;
  bfd_vma offset;
  int n, m, num;

  sec = bfd_get_section_by_name (output_bfd, secname);
  if (!sec)
    return -1;

  section_size = (sec->_cooked_size != 0 ? sec->_cooked_size : sec->_raw_size);
  BFD_ASSERT (section_size % 8 == 0);
  num = section_size / 8;

  contents = (bfd_byte *) bfd_malloc (section_size);
  table = (property_table_entry *)
    bfd_malloc (num * sizeof (property_table_entry));
  if (contents == 0 || 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_get_section_contents.  */
  sec->flags &= ~SEC_IN_MEMORY;

  if (! bfd_get_section_contents (output_bfd, sec, contents, 0, section_size))
    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);
      sec->_cooked_size = num * 8;
    }

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

  free (contents);
  return num;
}


/* Finish up the dynamic sections.  */

static bfd_boolean
elf_xtensa_finish_dynamic_sections (output_bfd, info)
     bfd *output_bfd;
     struct bfd_link_info *info;
{
  bfd *dynobj;
  asection *sdyn, *srelplt, *sgot;
  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->_raw_size == 4);
      if (sdyn == NULL)
	bfd_put_32 (output_bfd, (bfd_vma) 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 != NULL && srelplt->_raw_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->_raw_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->_cooked_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->_cooked_size != (sizeof (Elf32_External_Rela)
				    * srelgot->reloc_count)
	  || srelplt->_cooked_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->_raw_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->relocateable);
  num_xtlit_entries = elf_xtensa_combine_prop_entries (output_bfd, ".xt.lit");
  if (num_xtlit_entries < 0)
    return FALSE;

  dyncon = (Elf32_External_Dyn *) sdyn->contents;
  dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->_raw_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:
	  s = bfd_get_section_by_name (output_bfd, ".xt.lit");
	  BFD_ASSERT (s);
	  dyn.d_un.d_val = num_xtlit_entries;
	  break;

	case DT_XTENSA_GOT_LOC_OFF:
	  name = ".xt.lit";
	  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->_cooked_size ? s->_cooked_size : s->_raw_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->_cooked_size ? s->_cooked_size : s->_raw_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 (ibfd, obfd)
     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)
	("%s: incompatible machine type. Output is 0x%x. Input is 0x%x\n",
	 bfd_archive_filename (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 (abfd, 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;
}


extern flagword
elf_xtensa_get_private_bfd_flags (abfd)
     bfd *abfd;
{
  return elf_elfheader (abfd)->e_flags;
}


static bfd_boolean
elf_xtensa_print_private_bfd_data (abfd, farg)
     bfd *abfd;
     PTR 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 (abfd)
     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 (abfd, linker)
     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 (rela)
     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 (abfd, cookie, info, sec)
     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->_cooked_size ? sec->_cooked_size : sec->_raw_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_elf32_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);

      sec->_cooked_size = section_size - removed_bytes;
      /* Also shrink _raw_size.  See comments in relax_property_section.  */
      sec->_raw_size = sec->_cooked_size;
    }
  else
    {
      release_contents (sec, contents);
      release_internal_relocs (sec, cookie->rels);
    }

  return (removed_bytes != 0);
}


static bfd_boolean
elf_xtensa_discard_info (abfd, cookie, 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 (sec)
     asection *sec;
{
  return xtensa_is_property_section (sec);
}


/* Support for core dump NOTE sections.  */

static bfd_boolean
elf_xtensa_grok_prstatus (abfd, note)
     bfd *abfd;
     Elf_Internal_Note *note;
{
  int offset;
  unsigned int raw_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;
  raw_size = note->descsz - offset - 4;

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


static bfd_boolean
elf_xtensa_grok_psinfo (abfd, note)
     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 ()
{
  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 (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 (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 (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_l32r_opcode (void)
{
  static xtensa_opcode l32r_opcode = XTENSA_UNDEFINED;
  if (l32r_opcode == XTENSA_UNDEFINED)
    {
      l32r_opcode = xtensa_opcode_lookup (xtensa_default_isa, "l32r");
      BFD_ASSERT (l32r_opcode != XTENSA_UNDEFINED);
    }
  return l32r_opcode;
}


static bfd_vma
l32r_offset (addr, pc)
     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;
}


/* Get the operand number for a PC-relative relocation.
   If the relocation is not a PC-relative one, return (-1).  */

static int
get_relocation_opnd (irel)
     Elf_Internal_Rela *irel;
{
  if (ELF32_R_TYPE (irel->r_info) < R_XTENSA_OP0
      || ELF32_R_TYPE (irel->r_info) >= R_XTENSA_max)
    return -1;
  return ELF32_R_TYPE (irel->r_info) - R_XTENSA_OP0;
}


/* Get the opcode for a relocation.  */

static xtensa_opcode
get_relocation_opcode (sec, contents, irel)
     asection *sec;
     bfd_byte *contents;
     Elf_Internal_Rela *irel;
{
  static xtensa_insnbuf ibuff = NULL;
  xtensa_isa isa = xtensa_default_isa;

  if (get_relocation_opnd (irel) == -1)
    return XTENSA_UNDEFINED;

  if (contents == NULL)
    return XTENSA_UNDEFINED;

  if (sec->_raw_size <= irel->r_offset)
    return XTENSA_UNDEFINED;

  if (ibuff == NULL)
    ibuff = xtensa_insnbuf_alloc (isa);
      
  /* Decode the instruction.  */
  xtensa_insnbuf_from_chars (isa, ibuff, &contents[irel->r_offset]);
  return xtensa_decode_insn (isa, ibuff);
}


bfd_boolean
is_l32r_relocation (sec, contents, irel)
     asection *sec;
     bfd_byte *contents;
     Elf_Internal_Rela *irel;
{
  xtensa_opcode opcode;

  if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_OP1)
    return FALSE;
  
  opcode = get_relocation_opcode (sec, contents, irel);
  return (opcode == get_l32r_opcode ());
}

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

static bfd_reloc_status_type
elf_xtensa_do_asm_simplify (contents, address, content_length)
     bfd_byte *contents;
     bfd_vma address;
     bfd_vma content_length;
{
  static xtensa_insnbuf insnbuf = NULL;
  xtensa_opcode opcode;
  xtensa_operand operand;
  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);

  if (content_length < address)
    {
      (*_bfd_error_handler)
	("Attempt to convert L32R/CALLX to CALL failed\n");
      return bfd_reloc_other;
    }

  opcode = get_expanded_call_opcode (chbuf, content_length - address);
  direct_call_opcode = swap_callx_for_call_opcode (opcode);
  if (direct_call_opcode == XTENSA_UNDEFINED)
    {
      (*_bfd_error_handler)
	("Attempt to convert L32R/CALLX to CALL failed\n");
      return bfd_reloc_other;
    }
  
  /* Assemble a NOP ("or a1, a1, a1") into the 0 byte offset.  */
  opcode = xtensa_opcode_lookup (isa, "or");
  xtensa_encode_insn (isa, opcode, insnbuf);
  for (opn = 0; opn < 3; opn++) 
    {
      operand = xtensa_get_operand (isa, opcode, opn);
      xtensa_operand_set_field (operand, insnbuf, 1);
    }
  xtensa_insnbuf_to_chars (isa, insnbuf, chbuf);

  /* Assemble a CALL ("callN 0") into the 3 byte offset.  */
  xtensa_encode_insn (isa, direct_call_opcode, insnbuf);
  operand = xtensa_get_operand (isa, opcode, 0);
  xtensa_operand_set_field (operand, insnbuf, 0);
  xtensa_insnbuf_to_chars (isa, insnbuf, chbuf + 3);

  return bfd_reloc_ok;
}


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

  if (retval != bfd_reloc_ok)
    return retval;

  /* 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_OP0);
  return bfd_reloc_ok;
}


static xtensa_opcode
swap_callx_for_call_opcode (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" sequence, and
   if so, return the CALLX opcode.  If not, return XTENSA_UNDEFINED.  */

#define L32R_TARGET_REG_OPERAND 0
#define CALLN_SOURCE_OPERAND 0

static xtensa_opcode 
get_expanded_call_opcode (buf, bufsize)
     bfd_byte *buf;
     int bufsize;
{
  static xtensa_insnbuf insnbuf = NULL;
  xtensa_opcode opcode;
  xtensa_operand operand;
  xtensa_isa isa = xtensa_default_isa;
  uint32 regno, call_regno;
  
  /* Buffer must be at least 6 bytes.  */
  if (bufsize < 6)
    return XTENSA_UNDEFINED;

  if (insnbuf == NULL)
    insnbuf = xtensa_insnbuf_alloc (isa);
      
  xtensa_insnbuf_from_chars (isa, insnbuf, buf);
  opcode = xtensa_decode_insn (isa, insnbuf);
  
  if (opcode != get_l32r_opcode ())
    return XTENSA_UNDEFINED;
  
  operand = xtensa_get_operand (isa, opcode, L32R_TARGET_REG_OPERAND);
  regno = xtensa_operand_decode
    (operand, xtensa_operand_get_field (operand, insnbuf));
  
  /* Next instruction should be an CALLXn with operand 0 == regno.  */
  xtensa_insnbuf_from_chars (isa, insnbuf, 
			     buf + xtensa_insn_length (isa, opcode));
  opcode = xtensa_decode_insn (isa, insnbuf);
  
  if (!is_indirect_call_opcode (opcode))
    return XTENSA_UNDEFINED;
  
  operand = xtensa_get_operand (isa, opcode, CALLN_SOURCE_OPERAND);
  call_regno = xtensa_operand_decode
    (operand, xtensa_operand_get_field (operand, insnbuf));
  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.  */

typedef struct r_reloc_struct r_reloc;

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

static bfd_boolean r_reloc_is_const
  PARAMS ((const r_reloc *));
static void r_reloc_init
  PARAMS ((r_reloc *, bfd *, Elf_Internal_Rela *));
static bfd_vma r_reloc_get_target_offset
  PARAMS ((const r_reloc *));
static asection *r_reloc_get_section
  PARAMS ((const r_reloc *));
static bfd_boolean r_reloc_is_defined
  PARAMS ((const r_reloc *));
static struct elf_link_hash_entry *r_reloc_get_hash_entry
  PARAMS ((const r_reloc *));


/* 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 (r_rel)
     const r_reloc *r_rel;
{
  return (r_rel->abfd == NULL);
}


static void
r_reloc_init (r_rel, abfd, irel) 
     r_reloc *r_rel;
     bfd *abfd;
     Elf_Internal_Rela *irel;
{
  if (irel != NULL)
    {
      r_rel->rela = *irel;
      r_rel->abfd = abfd;
      r_rel->target_offset = r_reloc_get_target_offset (r_rel);
    }
  else
    memset (r_rel, 0, sizeof (r_reloc));
}


static bfd_vma
r_reloc_get_target_offset (r_rel)
     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 (r_rel)
     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 (r_rel)
     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 (r_rel)
     const r_reloc *r_rel;
{
  asection *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;
}


/* source_reloc: relocations that reference literal sections.  */

/* 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_operand opnd;
  bfd_boolean is_null;
};


static void init_source_reloc
  PARAMS ((source_reloc *, asection *, const r_reloc *, xtensa_operand));
static source_reloc *find_source_reloc
  PARAMS ((source_reloc *, int, asection *, Elf_Internal_Rela *));
static int source_reloc_compare
  PARAMS ((const PTR, const PTR));


static void
init_source_reloc (reloc, source_sec, r_rel, opnd)
     source_reloc *reloc;
     asection *source_sec;
     const r_reloc *r_rel;
     xtensa_operand opnd;
{
  reloc->source_sec = source_sec;
  reloc->r_rel = *r_rel;
  reloc->opnd = opnd;
  reloc->is_null = FALSE;
}


/* 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 (src_relocs, src_count, sec, irel)
     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 (ap, bp)
     const PTR ap;
     const PTR bp;
{
  const source_reloc *a = (const source_reloc *) ap;
  const source_reloc *b = (const source_reloc *) bp;

  return (a->r_rel.target_offset - b->r_rel.target_offset);
}


/* 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;
};

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;
};


static bfd_boolean is_same_value
  PARAMS ((const literal_value *, const literal_value *));
static value_map_hash_table *value_map_hash_table_init
  PARAMS ((void));
static unsigned hash_literal_value
  PARAMS ((const literal_value *));
static unsigned hash_bfd_vma
  PARAMS ((bfd_vma));
static value_map *get_cached_value
  PARAMS ((value_map_hash_table *, const literal_value *));
static value_map *add_value_map
  PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *));


static bfd_boolean
is_same_value (src1, src2)
     const literal_value *src1;
     const literal_value *src2;
{
  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 (r_reloc_get_target_offset (&src1->r_rel)
      != r_reloc_get_target_offset (&src2->r_rel))
    return FALSE;

  if (src1->value != src2->value)
    return FALSE;
  
  /* Now check for the same section and the same elf_hash.  */
  if (r_reloc_is_defined (&src1->r_rel))
    {
      if (r_reloc_get_section (&src1->r_rel)
	  != r_reloc_get_section (&src2->r_rel))
	return FALSE;
    }
  else
    {
      if (r_reloc_get_hash_entry (&src1->r_rel)
	  != r_reloc_get_hash_entry (&src2->r_rel))
	return FALSE;

      if (r_reloc_get_hash_entry (&src1->r_rel) == 0)
	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 ()
{
  value_map_hash_table *values;

  values = (value_map_hash_table *)
    bfd_malloc (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);

  return values;
}


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


static unsigned
hash_literal_value (src)
     const literal_value *src;
{
  unsigned hash_val;
  if (r_reloc_is_const (&src->r_rel))
    return hash_bfd_vma (src->value);

  hash_val = (hash_bfd_vma (r_reloc_get_target_offset (&src->r_rel))
	      + hash_bfd_vma (src->value));
  
  /* Now check for the same section and the same elf_hash.  */
  if (r_reloc_is_defined (&src->r_rel))
    hash_val += hash_bfd_vma ((bfd_vma) r_reloc_get_section (&src->r_rel));
  else
    hash_val += hash_bfd_vma ((bfd_vma) r_reloc_get_hash_entry (&src->r_rel));

  return hash_val;
}


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

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

  idx = hash_literal_value (val);
  idx = idx & (map->bucket_count - 1);
  bucket = map->buckets[idx];
  for (map_e = bucket; map_e; map_e = map_e->next)
    {
      if (is_same_value (&map_e->val, val))
	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 (map, val, loc)
     value_map_hash_table *map;
     const literal_value *val;
     const r_reloc *loc;
{
  value_map **bucket_p;
  unsigned idx;

  value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map));

  BFD_ASSERT (get_cached_value (map, val) == NULL);
  val_e->val = *val;
  val_e->loc = *loc;

  idx = hash_literal_value (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 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;
};


static void add_removed_literal
  PARAMS ((removed_literal_list *, const r_reloc *, const r_reloc *));
static removed_literal *find_removed_literal
  PARAMS ((removed_literal_list *, bfd_vma));
static bfd_vma offset_with_removed_literals
  PARAMS ((removed_literal_list *, bfd_vma));


/* 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_list, from, to)
     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 != NULL) 
	{
	  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_list, addr)
     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;
}


/* Adjust an offset in a section to compensate for literals that are
   being removed.  Search the list of removed literals and subtract
   4 bytes for every removed literal prior to the given address.  */

static bfd_vma 
offset_with_removed_literals (removed_list, addr)
     removed_literal_list *removed_list;
     bfd_vma addr;
{
  removed_literal *r = removed_list->head;
  unsigned num_bytes = 0;

  if (r == NULL)
    return addr;

  while (r && r->from.target_offset <= addr)
    {
      num_bytes += 4;
      r = r->next;
    }
  if (num_bytes > addr)
    return 0;
  return (addr - num_bytes);
}


/* 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.  */

typedef struct reloc_bfd_fix_struct reloc_bfd_fix;

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;
  
  reloc_bfd_fix *next;
};


static reloc_bfd_fix *reloc_bfd_fix_init
  PARAMS ((asection *, bfd_vma, unsigned, bfd *, asection *, bfd_vma));
static reloc_bfd_fix *get_bfd_fix
  PARAMS ((reloc_bfd_fix *, asection *, bfd_vma, unsigned));


static reloc_bfd_fix *
reloc_bfd_fix_init (src_sec, src_offset, src_type,
		    target_abfd, target_sec, target_offset)
     asection *src_sec;
     bfd_vma src_offset;
     unsigned src_type;
     bfd *target_abfd;
     asection *target_sec;
     bfd_vma target_offset;
{
  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;

  return fix;
}


static reloc_bfd_fix *
get_bfd_fix (fix_list, sec, offset, type)
     reloc_bfd_fix *fix_list;
     asection *sec;
     bfd_vma offset;
     unsigned type;
{
  reloc_bfd_fix *r;

  for (r = fix_list; r != NULL; r = r->next) 
    {
      if (r->src_sec == sec
	  && r->src_offset == offset
	  && r->src_type == type)
	return r;
    }
  return NULL;
}


/* Per-section data for relaxation.  */

struct xtensa_relax_info_struct
{
  bfd_boolean is_relaxable_literal_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;

  reloc_bfd_fix *fix_list;
};

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

static void init_xtensa_relax_info
  PARAMS ((asection *));
static xtensa_relax_info *get_xtensa_relax_info
  PARAMS ((asection *));
static void add_fix
  PARAMS ((asection *, reloc_bfd_fix *));


static bfd_boolean
elf_xtensa_new_section_hook (abfd, sec)
     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 = (PTR) sdata;

  return _bfd_elf_new_section_hook (abfd, sec);
}


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

  relax_info->is_relaxable_literal_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->fix_list = NULL;
}


static xtensa_relax_info *
get_xtensa_relax_info (sec)
     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
add_fix (src_sec, 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;
}


/* 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 (abfd, sec, keep_memory)
     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_elf32_link_read_relocs
		       (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL,
			keep_memory));
  return internal_relocs;
}


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


static void
release_internal_relocs (sec, 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 (abfd, sec, keep_memory)
     bfd *abfd;
     asection *sec;
     bfd_boolean keep_memory;
{
  bfd_byte *contents;

  contents = elf_section_data (sec)->this_hdr.contents;
  
  if (contents == NULL && sec->_raw_size != 0)
    {
      contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
      if (contents != NULL)
	{
	  if (! bfd_get_section_contents (abfd, sec, contents,
					  (file_ptr) 0, sec->_raw_size))
	    {
	      free (contents);
	      return NULL;
	    }
	  if (keep_memory) 
	    elf_section_data (sec)->this_hdr.contents = contents;
	}
    }
  return contents;
}


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


static void
release_contents (sec, 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 (input_bfd)
     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.  */

/* Local helper functions.  */
static bfd_boolean analyze_relocations
  PARAMS ((struct bfd_link_info *));
static bfd_boolean find_relaxable_sections
  PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
static bfd_boolean collect_source_relocs
  PARAMS ((bfd *, asection *, struct bfd_link_info *));
static bfd_boolean is_resolvable_asm_expansion
  PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *,
	   struct bfd_link_info *, bfd_boolean *));
static bfd_boolean remove_literals
  PARAMS ((bfd *, asection *, struct bfd_link_info *, value_map_hash_table *));
static bfd_boolean relax_section
  PARAMS ((bfd *, asection *, struct bfd_link_info *));
static bfd_boolean relax_property_section
  PARAMS ((bfd *, asection *, struct bfd_link_info *));
static bfd_boolean relax_section_symbols
  PARAMS ((bfd *, asection *));
static bfd_boolean relocations_reach
  PARAMS ((source_reloc *, int, const r_reloc *));
static void translate_reloc
  PARAMS ((const r_reloc *, r_reloc *));
static Elf_Internal_Rela *get_irel_at_offset
  PARAMS ((asection *, Elf_Internal_Rela *, bfd_vma));
static Elf_Internal_Rela *find_associated_l32r_irel
  PARAMS ((asection *, bfd_byte *, Elf_Internal_Rela *,
	   Elf_Internal_Rela *));
static void shrink_dynamic_reloc_sections
  PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *));


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

  if (!values)
    {
      /* Do some overall initialization for relaxation.  */
      values = value_map_hash_table_init ();
      relaxing_section = TRUE;
      if (!analyze_relocations (link_info))
	return FALSE;
    }
  *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 (!remove_literals (abfd, sec, link_info, values))
	return FALSE;
      *again = TRUE;
      break;

    case 1:
      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).  It then
   collect source_reloc information for all the relocations against
   those relaxable sections.  */

static bfd_boolean
analyze_relocations (link_info)
     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->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;
      }

  return TRUE;
}


/* Find all the literal 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 targetting 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 (abfd, sec, link_info, is_relaxable_p)
     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;

  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->_raw_size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  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);

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

      /* Count relocations against the target section.  */
      target_relax_info->src_count++;

      if (is_literal_section (target_sec)
	  && is_l32r_relocation (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 literal
   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 (abfd, sec, link_info)
     bfd *abfd;
     asection *sec;
     struct bfd_link_info *link_info;
{
  Elf_Internal_Rela *internal_relocs;
  bfd_byte *contents;
  bfd_boolean ok = TRUE;
  unsigned i;

  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->_raw_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);

      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)
	{
	  xtensa_opcode opcode;
	  xtensa_operand opnd;
	  source_reloc *s_reloc;
	  int src_next;

	  src_next = target_relax_info->src_next++;
	  s_reloc = &target_relax_info->src_relocs[src_next];

	  opcode = get_relocation_opcode (sec, contents, irel);
	  if (opcode == XTENSA_UNDEFINED)
	    opnd = NULL;
	  else
	    opnd = xtensa_get_operand (xtensa_default_isa, opcode,
				       get_relocation_opnd (irel));

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

  /* 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 remove_literals(), along with the associated
	     literal.  */
	  l32r_irel = find_associated_l32r_irel (sec, contents,
						 irel, internal_relocs);
	  if (l32r_irel == NULL)
	    continue;

	  r_reloc_init (&r_rel, abfd, l32r_irel);

	  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)
	    {
	      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 (abfd, sec, contents, irel, link_info,
			     is_reachable_p)
     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;

  *is_reachable_p = FALSE;

  if (contents == NULL)
    return FALSE;

  if (ELF32_R_TYPE (irel->r_info) != R_XTENSA_ASM_EXPAND) 
    return FALSE;
  
  opcode = get_expanded_call_opcode (contents + irel->r_offset,
				     sec->_raw_size - irel->r_offset);
  
  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);
  if (!r_reloc_is_defined (&r_rel))
    return FALSE;

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

  /* 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 relocateable 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->relocateable
      && (target_sec->output_section != sec->output_section))
    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
    (xtensa_get_operand (xtensa_default_isa, 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 (sec, contents, other_irel, internal_relocs)
     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 (sec, contents, irel))
	return irel;
    }

  return NULL;
}

/* First relaxation pass.  */

/* If the section is relaxable (i.e., a literal section), 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 
remove_literals (abfd, sec, link_info, values)
     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;
  bfd_boolean ok = TRUE;
  int i;

  /* 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);

  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec->_raw_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);

  for (i = 0; i < relax_info->src_count; i++)
    {
      source_reloc *rel;
      Elf_Internal_Rela *irel = NULL;
      literal_value val;
      value_map *val_map;

      rel = &src_relocs[i];
      irel = get_irel_at_offset (sec, internal_relocs,
				 rel->r_rel.target_offset);

      /* 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 && (src_relocs[i-1].r_rel.target_offset
		     == rel->r_rel.target_offset))
	continue;

      /* 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 (rel->is_null
	  && (i == relax_info->src_count - 1
	      || (src_relocs[i+1].r_rel.target_offset
		  != 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);

	  /* 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);
	    }

	  continue;
	}

      /* Find the literal value.  */
      r_reloc_init (&val.r_rel, abfd, irel);
      BFD_ASSERT (rel->r_rel.target_offset < sec->_raw_size);
      val.value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset);
          
      /* Check if we've seen another literal with the same value.  */
      val_map = get_cached_value (values, &val);
      if (val_map != NULL) 
	{
	  /* First check that THIS and all the other relocs to this
	     literal will FIT if we move them to the new address.  */

	  if (relocations_reach (rel, relax_info->src_count - i,
				 &val_map->loc))
	    {
	      /* Mark that the literal will be coalesced.  */
	      add_removed_literal (&relax_info->removed_list,
				   &rel->r_rel, &val_map->loc);
	    }
	  else
	    {
	      /* Relocations do not reach -- do not remove this literal.  */
	      val_map->loc = rel->r_rel;
	    }
	}
      else
	{
	  /* This is the first time we've seen this literal value.  */
	  BFD_ASSERT (sec == r_reloc_get_section (&rel->r_rel));
	  add_value_map (values, &val, &rel->r_rel);
	}
    }

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


/* 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 (reloc, remaining_relocs, r_rel)
     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 NULL operand means it is not a PC-relative relocation, so
         the literal can be moved anywhere.  */
      if (reloc[i].opnd)
	{
	  /* 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].opnd, source_address, dest_address))
	    return FALSE;
	}
    }

  return TRUE;
}


/* WARNING: linear search here.  If the relocation are in order by
   address, we can use a faster binary search.  ALSO, we assume that
   there is only 1 non-NONE relocation per address.  */

static Elf_Internal_Rela *
get_irel_at_offset (sec, internal_relocs, offset)
     asection *sec;
     Elf_Internal_Rela *internal_relocs;
     bfd_vma offset;
{
  unsigned i;
  if (!internal_relocs) 
    return NULL;
  for (i = 0; i < sec->reloc_count; i++)
    {
      Elf_Internal_Rela *irel = &internal_relocs[i];
      if (irel->r_offset == offset
	  && ELF32_R_TYPE (irel->r_info) != R_XTENSA_NONE)
	return irel;
    }
  return NULL;
}


/* 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
   cooked_size.  */

bfd_boolean 
relax_section (abfd, sec, link_info)
     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;

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

  /* 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->_raw_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;
	  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;

	  r_type = ELF32_R_TYPE (irel->r_info);
	  r_reloc_init (&r_rel, abfd, irel);
	
	  if (relax_info->is_relaxable_literal_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_literals
		    (&relax_info->removed_list, irel->r_offset);
		  continue;
		}
	      source_offset =
		offset_with_removed_literals (&relax_info->removed_list,
					      irel->r_offset);
	      irel->r_offset = source_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)
	    {
	      r_reloc new_rel;
	      reloc_bfd_fix *fix;

	      translate_reloc (&r_rel, &new_rel);

	      /* 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.  */

	      fix = reloc_bfd_fix_init (sec, source_offset, r_type, 0,
					r_reloc_get_section (&new_rel),
					new_rel.target_offset);
	      add_fix (sec, fix);
	    }

	  pin_internal_relocs (sec, internal_relocs);
	}
    }

  if (relax_info->is_relaxable_literal_section)
    {
      /* Walk through the contents and delete literals that are not needed 
         anymore.  */

      unsigned long size = sec->_cooked_size;
      unsigned long removed = 0;

      removed_literal *reloc = relax_info->removed_list.head;
      for (; reloc; reloc = reloc->next) 
	{
	  unsigned long upper = sec->_raw_size;
	  bfd_vma start = reloc->from.target_offset + 4;
	  if (reloc->next)
	    upper = reloc->next->from.target_offset;
	  if (upper - start != 0) 
	    {
	      BFD_ASSERT (start <= upper);
	      memmove (contents + start - removed - 4,
		       contents + start,
		       upper - start );
	      pin_contents (sec, contents);
	    }
	  removed += 4;
	  size -= 4;
	}

      /* Change the section size.  */
      sec->_cooked_size = size;
      /* Also shrink _raw_size.  (The code in relocate_section that
	 checks that relocations are within the section must use
	 _raw_size because of the way the stabs sections are relaxed;
	 shrinking _raw_size means that these checks will not be
	 unnecessarily lax.)  */
      sec->_raw_size = size;
    }
  
 error_return:
  release_internal_relocs (sec, internal_relocs);
  release_contents (sec, contents);
  return ok;
}


/* Fix up a relocation to take account of removed literals.  */

static void
translate_reloc (orig_rel, new_rel)
     const r_reloc *orig_rel;
     r_reloc *new_rel;
{
  asection *sec;
  xtensa_relax_info *relax_info;
  removed_literal *removed;
  unsigned long new_offset;

  *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)
    return;

  /* Check if the original relocation is against a literal being removed.  */
  removed = find_removed_literal (&relax_info->removed_list,
				  orig_rel->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 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)
	    return;
	}
    }

  /* ...and the target address may have been moved within its section.  */
  new_offset = offset_with_removed_literals (&relax_info->removed_list,
					     new_rel->target_offset);

  /* Modify the offset and addend.  */
  new_rel->target_offset = new_offset;
  new_rel->rela.r_addend += (new_offset - new_rel->target_offset);
}


/* 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 (info, abfd, input_section, rel)
     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 (info, h);

  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->_cooked_size >= sizeof (Elf32_External_Rela));
      srel->_cooked_size -= sizeof (Elf32_External_Rela);

      /* Also shrink _raw_size.  (This seems wrong but other bfd code seems
	 to assume that linker-created sections will never be relaxed and
	 hence _raw_size must always equal _cooked_size.) */
      srel->_raw_size = srel->_cooked_size;

      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->_cooked_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->_cooked_size -= 2 * sizeof (Elf32_External_Rela);
	      /* Shrink _raw_size (see comment above).  */
	      srelgot->_raw_size = srelgot->_cooked_size;

	      sgotplt->_cooked_size -= 8;

	      /* There should be only one entry left (and it will be
		 removed below).  */
	      BFD_ASSERT (sgotplt->_cooked_size == 4);
	      BFD_ASSERT (splt->_cooked_size == PLT_ENTRY_SIZE);
	    }

	  BFD_ASSERT (sgotplt->_cooked_size >= 4);
	  BFD_ASSERT (splt->_cooked_size >= PLT_ENTRY_SIZE);

	  sgotplt->_cooked_size -= 4;
	  splt->_cooked_size -= PLT_ENTRY_SIZE;

	  /* Shrink _raw_sizes (see comment above).  */
	  sgotplt->_raw_size = sgotplt->_cooked_size;
	  splt->_raw_size = splt->_cooked_size;
	}
    }
}


/* 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 (abfd, sec, link_info)
     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;

  internal_relocs = retrieve_internal_relocs (abfd, sec, 
					      link_info->keep_memory);
  contents = retrieve_contents (abfd, sec, link_info->keep_memory);
  if (contents == NULL && sec->_raw_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;
	  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, 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;

	  r_reloc_init (&r_rel, abfd, irel);

	  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)
	    {
	      /* Translate the relocation's destination.  */
	      bfd_vma new_offset;
	      bfd_vma new_end_offset;
	      bfd_byte *size_p;
	      long old_size, new_size;

	      new_offset =
		offset_with_removed_literals (&target_relax_info->removed_list,
					      r_rel.target_offset);

	      /* Assert that we are not out of bounds.  */
	      size_p = &contents[irel->r_offset + 4];
	      old_size = bfd_get_32 (abfd, &contents[irel->r_offset + 4]);

	      new_end_offset =
		offset_with_removed_literals (&target_relax_info->removed_list,
					      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 != r_rel.target_offset)
		{
		  bfd_vma diff = new_offset - 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)
    {
      Elf_Internal_Rela *last_irel = NULL;
      int removed_bytes = 0;
      bfd_vma offset, last_irel_offset;
      bfd_vma section_size;

      /* 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->_cooked_size ? sec->_cooked_size : sec->_raw_size);
      BFD_ASSERT (section_size % 8 == 0);

      for (offset = 0; offset < section_size; offset += 8)
	{
	  Elf_Internal_Rela *irel, *next_irel;
	  bfd_vma bytes_to_remove, size, actual_offset;
	  bfd_boolean remove_this_irel;

	  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]);

	  /* 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 isn't a reloc on the size field.  */
	  if (irel && irel->r_offset == offset + 4)
	    {
	      irel->r_offset -= removed_bytes;
	      last_irel_offset = irel->r_offset;
	    }
	  else if (next_irel && next_irel->r_offset == offset + 4)
	    {
	      nexti += 1;
	      irel->r_offset -= removed_bytes;
	      next_irel->r_offset -= removed_bytes;
	      last_irel_offset = next_irel->r_offset;
	    }
	  else if (size == 0)
	    {
	      /* Always remove entries with zero size.  */
	      bytes_to_remove = 8;
	      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)
		    {
		      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 ((ELF32_R_SYM (irel->r_info) ==
			   ELF32_R_SYM (last_irel->r_info))
			  && (old_address + old_size == new_address)) 
			{
			  /* fix the old size */
			  bfd_put_32 (abfd, old_size + size,
				      &contents[last_irel->r_offset + 4]);
			  bytes_to_remove = 8;
			  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 + 8 < section_size)
		memmove (&contents[actual_offset],
			 &contents[actual_offset+8],
			 section_size - offset - 8);
	    }
	}

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

	  sec->_cooked_size = section_size - removed_bytes;
	  /* Also shrink _raw_size.  (The code in relocate_section that
	     checks that relocations are within the section must use
	     _raw_size because of the way the stabs sections are
	     relaxed; shrinking _raw_size means that these checks will
	     not be unnecessarily lax.)  */
	  sec->_raw_size = sec->_cooked_size;
	}
    }
	  
 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 (abfd, sec)
     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)
    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_literals
	    (&relax_info->removed_list, isym->st_value);
	  if (new_address != isym->st_value)
	    isym->st_value = new_address;
	}
    }

  /* 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_literals
	    (&relax_info->removed_list, sym_hash->root.u.def.value);
	  if (new_address != sym_hash->root.u.def.value)
	    sym_hash->root.u.def.value = new_address;
	}
    }

  return TRUE;
}


/* "Fix" handling functions, called while performing relocations.  */

static void
do_fix_for_relocateable_link (rel, input_bfd, input_section)
     Elf_Internal_Rela *rel;
     bfd *input_bfd;
     asection *input_section;
{
  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_list;
  reloc_bfd_fix *fix;

  if (r_type == R_XTENSA_NONE)
    return;

  fix_list = (get_xtensa_relax_info (input_section))->fix_list;
  if (fix_list == NULL)
    return;

  fix = get_bfd_fix (fix_list, input_section, rel->r_offset, r_type);
  if (fix == NULL)
    return;

  r_reloc_init (&r_rel, input_bfd, rel);
  old_sec = r_reloc_get_section (&r_rel);
  old_offset = r_reloc_get_target_offset (&r_rel);
	      
  if (old_sec == NULL || !r_reloc_is_defined (&r_rel))
    {
      BFD_ASSERT (r_type == R_XTENSA_ASM_EXPAND);
      /* 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));
    }
}


static void
do_fix_for_final_link (rel, input_section, relocationp)
     Elf_Internal_Rela *rel;
     asection *input_section;
     bfd_vma *relocationp;
{
  asection *sec;
  int r_type = ELF32_R_TYPE (rel->r_info);
  reloc_bfd_fix *fix_list;
  reloc_bfd_fix *fix;

  if (r_type == R_XTENSA_NONE)
    return;

  fix_list = (get_xtensa_relax_info (input_section))->fix_list;
  if (fix_list == NULL)
    return;

  fix = get_bfd_fix (fix_list, input_section, rel->r_offset, r_type);
  if (fix == NULL)
    return;

  sec = fix->target_sec;
  *relocationp = (sec->output_section->vma
		  + sec->output_offset
		  + fix->target_offset - rel->r_addend);
}


/* Miscellaneous utility functions....  */

static asection *
elf_xtensa_get_plt_section (dynobj, chunk)
     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 (dynobj, chunk)
     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 (abfd, r_symndx)
     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 (abfd, r_symndx)
     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 (abfd, r_symndx)
     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
pcrel_reloc_fits (opnd, self_address, dest_address)
     xtensa_operand opnd;
     bfd_vma self_address;
     bfd_vma dest_address;
{
  uint32 new_address =
    xtensa_operand_do_reloc (opnd, dest_address, self_address);
  return (xtensa_operand_encode (opnd, &new_address)
	  == xtensa_encode_result_ok);
}


static bfd_boolean 
xtensa_is_property_section (sec)
     asection *sec;
{
  static int len = sizeof (".gnu.linkonce.t.") - 1;

  return (strcmp (".xt.insn", sec->name) == 0
	  || strcmp (".xt.lit", sec->name) == 0
	  || strncmp (".gnu.linkonce.x.", sec->name, len) == 0
	  || strncmp (".gnu.linkonce.p.", sec->name, len) == 0);
}


static bfd_boolean
is_literal_section (sec)
     asection *sec;
{
  /* FIXME: the current definition of this leaves a lot to be desired....  */
  if (sec == NULL || sec->name == NULL)
    return FALSE;
  return (strstr (sec->name, "literal") != NULL);
}


static int
internal_reloc_compare (ap, bp)
     const PTR ap;
     const PTR bp;
{
  const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap;
  const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp;

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


static bfd_boolean
get_is_linkonce_section (abfd, sec)
     bfd *abfd ATTRIBUTE_UNUSED;
     asection *sec;
{
  flagword flags, link_once_flags;
  bfd_boolean is_linkonce = FALSE;;

  flags = bfd_get_section_flags (abfd, sec);
  link_once_flags = (flags & SEC_LINK_ONCE);
  if (link_once_flags != 0)
    is_linkonce = TRUE;

  /* In order for this to be useful to the assembler
     before the linkonce flag is set we need to
     check for the GNU extension name.  */
  if (!is_linkonce &&
      strncmp (sec->name, ".gnu.linkonce", sizeof ".gnu.linkonce" - 1) == 0)
    is_linkonce = TRUE;
  
  return is_linkonce;
}


char *
xtensa_get_property_section_name (abfd, sec, base_name)
     bfd *abfd;
     asection *sec;
     const char * base_name;
{
  char *table_sec_name = NULL;
  bfd_boolean is_linkonce;

  is_linkonce = get_is_linkonce_section (abfd, sec);

  if (!is_linkonce)
    {
      table_sec_name = strdup (base_name);
    }
  else
    {
      static size_t prefix_len = sizeof (".gnu.linkonce.t.") - 1;
      size_t len = strlen (sec->name) + 1;
      char repl_char = '\0';
      const char *segname = sec->name;

      if (strncmp (segname, ".gnu.linkonce.t.", prefix_len) == 0)
	{
	  if (strcmp (base_name, ".xt.insn") == 0) 
	    repl_char = 'x';
	  else if (strcmp (base_name, ".xt.lit") == 0) 
	    repl_char = 'p';
	}
      
      if (repl_char != '\0')
	{
	  char *name = (char *) bfd_malloc (len);
	  memcpy (name, sec->name, len);
	  name[prefix_len - 2] = repl_char;
	  table_sec_name = name;
	}
      else
	{
	  size_t base_len = strlen (base_name) + 1;
	  char *name = (char *) bfd_malloc (len + base_len);
	  memcpy (name, sec->name, len - 1);
	  memcpy (name + len - 1, base_name, base_len);
	  table_sec_name = name;
	}
    }

  return table_sec_name;
}

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

bfd_boolean
xtensa_callback_required_dependence (abfd, sec, link_info, callback, closure)
     bfd *abfd;
     asection *sec;
     struct bfd_link_info *link_info;
     deps_callback_t callback;
     PTR closure;
{
  Elf_Internal_Rela *internal_relocs;
  bfd_byte *contents;
  unsigned i;
  bfd_boolean ok = TRUE;

  /* ".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->_raw_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->_raw_size != 0)
    {
      ok = FALSE;
      goto error_return;
    }

  if (xtensa_default_isa == NULL)
    xtensa_isa_init ();

  for (i = 0; i < sec->reloc_count; i++) 
    {
      Elf_Internal_Rela *irel = &internal_relocs[i];
      if (is_l32r_relocation (sec, contents, irel))
	{
	  r_reloc l32r_rel;
	  asection *target_sec;
	  bfd_vma target_offset;
	  
	  r_reloc_init (&l32r_rel, abfd, irel);
	  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 = r_reloc_get_target_offset (&l32r_rel);
	    }
	  (*callback) (sec, irel->r_offset, target_sec, target_offset,
		       closure);
	}
    }

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


#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
   (e.g., prep_headers() in elf.c) 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_final_link	     bfd_elf32_bfd_final_link
#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_copy_indirect_symbol     elf_xtensa_copy_indirect_symbol
#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

#include "elf32-target.h"
