/* 32-bit ELF support for TI PRU.
   Copyright (C) 2014-2020 Free Software Foundation, Inc.
   Contributed by Dimitar Dimitrov <dimitar@dinux.eu>
   Based on elf32-nios2.c

   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 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

/* This file handles TI PRU ELF targets.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "bfdlink.h"
#include "genlink.h"
#include "elf-bfd.h"
#include "elf/pru.h"
#include "opcode/pru.h"
#include "libiberty.h"

/* All users of this file have bfd_octets_per_byte (abfd, sec) == 1.  */
#define OCTETS_PER_BYTE(ABFD, SEC) 1

#define SWAP_VALS(A,B)		      \
  do {				      \
      (A) ^= (B);		      \
      (B) ^= (A);		      \
      (A) ^= (B);		      \
  } while (0)

/* Enable debugging printout at stdout with this variable.  */
static bfd_boolean debug_relax = FALSE;

/* Forward declarations.  */
static bfd_reloc_status_type pru_elf32_pmem_relocate
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type pru_elf32_s10_pcrel_relocate
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type pru_elf32_u8_pcrel_relocate
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type pru_elf32_ldi32_relocate
  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
static bfd_reloc_status_type bfd_elf_pru_diff_relocate
  (bfd *, arelent *, asymbol *, void *,	asection *, bfd *, char **);

/* Target vector.  */
extern const bfd_target pru_elf32_vec;

/* The relocation table used for SHT_REL sections.  */
static reloc_howto_type elf_pru_howto_table_rel[] = {
  /* No relocation.  */
  HOWTO (R_PRU_NONE,		/* type */
	 0,			/* rightshift */
	 0,			/* size (0 = byte, 1 = short, 2 = long) */
	 3,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont,/* complain_on_overflow */
	 bfd_elf_generic_reloc,	/* special_function */
	 "R_PRU_NONE",		/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0,			/* dst_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_PRU_16_PMEM,
	 2,
	 1,			/* short */
	 32,
	 FALSE,
	 0,
	 complain_overflow_dont,
	 bfd_elf_generic_reloc,
	 "R_PRU_16_PMEM",
	 FALSE,
	 0,			/* src_mask */
	 0xffff,
	 FALSE),

  HOWTO (R_PRU_U16_PMEMIMM,
	 2,
	 2,
	 32,
	 FALSE,
	 8,
	 complain_overflow_unsigned,
	 pru_elf32_pmem_relocate,
	 "R_PRU_U16_PMEMIMM",
	 FALSE,
	 0,			/* src_mask */
	 0x00ffff00,
	 FALSE),

  HOWTO (R_PRU_BFD_RELOC_16,
	 0,
	 1,			/* short */
	 16,
	 FALSE,
	 0,
	 complain_overflow_bitfield,
	 bfd_elf_generic_reloc,
	 "R_PRU_BFD_RELOC16",
	 FALSE,
	 0,			/* src_mask */
	 0x0000ffff,
	 FALSE),

  /* 16-bit unsigned immediate relocation.  */
  HOWTO (R_PRU_U16,		/* type */
	 0,			/* rightshift */
	 2,			/* size (0 = byte, 1 = short, 2 = long) */
	 16,			/* bitsize */
	 FALSE,			/* pc_relative */
	 8,			/* bitpos */
	 complain_overflow_unsigned,	/* complain on overflow */
	 bfd_elf_generic_reloc,	/* special function */
	 "R_PRU_U16",		/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0x00ffff00,		/* dest_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_PRU_32_PMEM,
	 2,
	 2,			/* long */
	 32,
	 FALSE,
	 0,
	 complain_overflow_dont,
	 pru_elf32_pmem_relocate,
	 "R_PRU_32_PMEM",
	 FALSE,
	 0,			/* src_mask */
	 0xffffffff,
	 FALSE),

  HOWTO (R_PRU_BFD_RELOC_32,
	 0,
	 2,			/* long */
	 32,
	 FALSE,
	 0,
	 complain_overflow_dont,
	 bfd_elf_generic_reloc,
	 "R_PRU_BFD_RELOC32",
	 FALSE,
	 0,			/* src_mask */
	 0xffffffff,
	 FALSE),

  HOWTO (R_PRU_S10_PCREL,
	 2,
	 2,
	 10,
	 TRUE,
	 0,
	 complain_overflow_bitfield,
	 pru_elf32_s10_pcrel_relocate,
	 "R_PRU_S10_PCREL",
	 FALSE,
	 0,			/* src_mask */
	 0x060000ff,
	 TRUE),

  HOWTO (R_PRU_U8_PCREL,
	 2,
	 2,
	 8,
	 TRUE,
	 0,
	 complain_overflow_unsigned,
	 pru_elf32_u8_pcrel_relocate,
	 "R_PRU_U8_PCREL",
	 FALSE,
	 0,			/* src_mask */
	 0x000000ff,
	 TRUE),

  HOWTO (R_PRU_LDI32,
	 0,			/* rightshift */
	 4,			/* size (4 = 8bytes) */
	 32,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_unsigned, /* complain on overflow */
	 pru_elf32_ldi32_relocate, /* special function */
	 "R_PRU_LDI32",		/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dest_mask */
	 FALSE),		/* pcrel_offset */

  /* GNU-specific relocations.  */
  HOWTO (R_PRU_GNU_BFD_RELOC_8,
	 0,
	 0,			/* byte */
	 8,
	 FALSE,
	 0,
	 complain_overflow_bitfield,
	 bfd_elf_generic_reloc,
	 "R_PRU_BFD_RELOC8",
	 FALSE,
	 0,			/* src_mask */
	 0x000000ff,
	 FALSE),

  HOWTO (R_PRU_GNU_DIFF8,	/* type */
	 0,			/* rightshift */
	 0,			/* size (0 = byte, 1 = short, 2 = long) */
	 8,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 bfd_elf_pru_diff_relocate, /* special_function */
	 "R_PRU_DIFF8",		/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xff,			/* dst_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_PRU_GNU_DIFF16,	/* type */
	 0,			/* rightshift */
	 1,			/* size (0 = byte, 1 = short, 2 = long) */
	 16,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 bfd_elf_pru_diff_relocate,/* special_function */
	 "R_PRU_DIFF16",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_PRU_GNU_DIFF32,	/* type */
	 0,			/* rightshift */
	 2,			/* size (0 = byte, 1 = short, 2 = long) */
	 32,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 bfd_elf_pru_diff_relocate,/* special_function */
	 "R_PRU_DIFF32",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_PRU_GNU_DIFF16_PMEM,	/* type */
	 0,			/* rightshift */
	 1,			/* size (0 = byte, 1 = short, 2 = long) */
	 16,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 bfd_elf_pru_diff_relocate,/* special_function */
	 "R_PRU_DIFF16_PMEM",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

  HOWTO (R_PRU_GNU_DIFF32_PMEM, /* type */
	 0,			/* rightshift */
	 2,			/* size (0 = byte, 1 = short, 2 = long) */
	 32,			/* bitsize */
	 FALSE,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_bitfield, /* complain_on_overflow */
	 bfd_elf_pru_diff_relocate,/* special_function */
	 "R_PRU_DIFF32_PMEM",	/* name */
	 FALSE,			/* partial_inplace */
	 0,			/* src_mask */
	 0xffffffff,		/* dst_mask */
	 FALSE),		/* pcrel_offset */

/* Add other relocations here.  */
};

static unsigned char elf_code_to_howto_index[R_PRU_ILLEGAL + 1];

/* Return the howto for relocation RTYPE.  */

static reloc_howto_type *
lookup_howto (unsigned int rtype)
{
  static bfd_boolean initialized = FALSE;
  int i;
  int howto_tbl_size = (int) (sizeof (elf_pru_howto_table_rel)
			      / sizeof (elf_pru_howto_table_rel[0]));

  if (! initialized)
    {
      initialized = TRUE;
      memset (elf_code_to_howto_index, 0xff,
	      sizeof (elf_code_to_howto_index));
      for (i = 0; i < howto_tbl_size; i++)
	elf_code_to_howto_index[elf_pru_howto_table_rel[i].type] = i;
    }

  if (rtype > R_PRU_ILLEGAL)
    return NULL;
  i = elf_code_to_howto_index[rtype];
  if (i >= howto_tbl_size)
    return NULL;
  return elf_pru_howto_table_rel + i;
}

/* Map for converting BFD reloc types to PRU reloc types.  */

struct elf_reloc_map
{
  bfd_reloc_code_real_type bfd_val;
  enum elf_pru_reloc_type elf_val;
};

static const struct elf_reloc_map pru_reloc_map[] =
{
  {BFD_RELOC_NONE, R_PRU_NONE},
  {BFD_RELOC_PRU_16_PMEM, R_PRU_16_PMEM},
  {BFD_RELOC_PRU_U16_PMEMIMM, R_PRU_U16_PMEMIMM},
  {BFD_RELOC_16, R_PRU_BFD_RELOC_16},
  {BFD_RELOC_PRU_U16, R_PRU_U16},
  {BFD_RELOC_PRU_32_PMEM, R_PRU_32_PMEM},
  {BFD_RELOC_32, R_PRU_BFD_RELOC_32},
  {BFD_RELOC_PRU_S10_PCREL, R_PRU_S10_PCREL},
  {BFD_RELOC_PRU_U8_PCREL, R_PRU_U8_PCREL},
  {BFD_RELOC_PRU_LDI32, R_PRU_LDI32},

  {BFD_RELOC_8, R_PRU_GNU_BFD_RELOC_8},
  {BFD_RELOC_PRU_GNU_DIFF8, R_PRU_GNU_DIFF8},
  {BFD_RELOC_PRU_GNU_DIFF16, R_PRU_GNU_DIFF16},
  {BFD_RELOC_PRU_GNU_DIFF32, R_PRU_GNU_DIFF32},
  {BFD_RELOC_PRU_GNU_DIFF16_PMEM, R_PRU_GNU_DIFF16_PMEM},
  {BFD_RELOC_PRU_GNU_DIFF32_PMEM, R_PRU_GNU_DIFF32_PMEM},
};


/* Assorted hash table functions.  */

/* Create an entry in a PRU ELF linker hash table.  */

static struct bfd_hash_entry *
link_hash_newfunc (struct bfd_hash_entry *entry,
		   struct bfd_hash_table *table, const char *string)
{
  /* Allocate the structure if it has not already been allocated by a
     subclass.  */
  if (entry == NULL)
    {
      entry = bfd_hash_allocate (table,
				 sizeof (struct elf_link_hash_entry));
      if (entry == NULL)
	return entry;
    }

  /* Call the allocation method of the superclass.  */
  entry = _bfd_elf_link_hash_newfunc (entry, table, string);

  return entry;
}

/* Implement bfd_elf32_bfd_reloc_type_lookup:
   Given a BFD reloc type, return a howto structure.  */

static reloc_howto_type *
pru_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
				   bfd_reloc_code_real_type code)
{
  unsigned int i;

  for (i = 0; i < ARRAY_SIZE (pru_reloc_map); ++i)
    if (pru_reloc_map[i].bfd_val == code)
      return lookup_howto ((unsigned int) pru_reloc_map[i].elf_val);
  return NULL;
}

/* Implement bfd_elf32_bfd_reloc_name_lookup:
   Given a reloc name, return a howto structure.  */

static reloc_howto_type *
pru_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
				   const char *r_name)
{
  unsigned int i;

  for (i = 0; i < ARRAY_SIZE (elf_pru_howto_table_rel); i++)
    if (elf_pru_howto_table_rel[i].name
	&& strcasecmp (elf_pru_howto_table_rel[i].name, r_name) == 0)
      return &elf_pru_howto_table_rel[i];

  return NULL;
}

/* Implement elf_info_to_howto:
   Given a ELF32 relocation, fill in a arelent structure.  */

static bfd_boolean
pru_elf32_info_to_howto (bfd *abfd, arelent *cache_ptr,
			 Elf_Internal_Rela *dst)
{
  unsigned int r_type;

  r_type = ELF32_R_TYPE (dst->r_info);
  if (r_type >= R_PRU_ILLEGAL)
    {
      /* xgettext:c-format */
      _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r_type);
      bfd_set_error (bfd_error_bad_value);
      return FALSE;
    }

  cache_ptr->howto = lookup_howto (r_type);
  return cache_ptr->howto != NULL;
}

/* Do the relocations that require special handling.  */
/* Produce a word address for program memory.  Linker scripts will put .text
   at a high offset in order to differentiate it from .data.  So here we also
   mask the high bits of PMEM address.

   But why 1MB when internal Program Memory much smaller? We want to catch
   unintended overflows.

   Why not use (1<<31) as an offset and a mask? Sitara DDRAM usually resides
   there, and users might want to put some shared carveout memory region in
   their linker scripts.  So 0x80000000 might be a valid .data address.

   Note that we still keep and pass down the original howto.  This way we
   can reuse this function for several different relocations.  */
static bfd_reloc_status_type
pru_elf32_do_pmem_relocate (bfd *abfd, reloc_howto_type *howto,
			    asection *input_section,
			    bfd_byte *data, bfd_vma offset,
			    bfd_vma symbol_value, bfd_vma addend)
{
  symbol_value = symbol_value + addend;
  addend = 0;
  symbol_value &= 0x3fffff;
  return _bfd_final_link_relocate (howto, abfd, input_section,
				   data, offset, symbol_value, addend);
}

/* Direct copy of _bfd_final_link_relocate, but with special
   "fill-in".  This copy-paste mumbo jumbo is only needed because BFD
   cannot deal correctly with non-contiguous bit fields.  */
static bfd_reloc_status_type
pru_elf32_do_s10_pcrel_relocate (bfd *input_bfd, reloc_howto_type *howto,
				 asection *input_section,
				 bfd_byte *contents, bfd_vma address,
				 bfd_vma relocation, bfd_vma addend)
{
  bfd_byte *location;
  bfd_vma x = 0;
  bfd_vma qboff;
  bfd_reloc_status_type flag = bfd_reloc_ok;

  /* Sanity check the address.  */
  if (address > bfd_get_section_limit (input_bfd, input_section))
    return bfd_reloc_outofrange;

  BFD_ASSERT (howto->pc_relative);
  BFD_ASSERT (howto->pcrel_offset);

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

  location = contents + address;

  /* Get the value we are going to relocate.  */
  BFD_ASSERT (bfd_get_reloc_size (howto) == 4);
  x = bfd_get_32 (input_bfd, location);

  qboff = GET_BROFF_SIGNED (x) << howto->rightshift;
  relocation += qboff;

  BFD_ASSERT (howto->complain_on_overflow == complain_overflow_bitfield);

  if (relocation > 2047 && relocation < (bfd_vma)-2048l)
    flag = bfd_reloc_overflow;

  /* Check that target address is word-aligned.  */
  if (relocation & ((1 << howto->rightshift) - 1))
    flag = bfd_reloc_outofrange;

  relocation >>= (bfd_vma) howto->rightshift;

  /* Fill-in the RELOCATION to the right bits of X.  */
  SET_BROFF_URAW (x, relocation);

  bfd_put_32 (input_bfd, x, location);

  return flag;
}

static bfd_reloc_status_type
pru_elf32_do_u8_pcrel_relocate (bfd *abfd, reloc_howto_type *howto,
				asection *input_section,
				bfd_byte *data, bfd_vma offset,
				bfd_vma symbol_value, bfd_vma addend)
{
  bfd_vma relocation;

  BFD_ASSERT (howto->pc_relative);
  BFD_ASSERT (howto->pcrel_offset);

  relocation = symbol_value + addend - (input_section->output_section->vma
		+ input_section->output_offset) - offset;
  relocation >>= howto->rightshift;

  /* 0 and 1 are invalid target labels for LOOP.  We cannot
     encode this info in HOWTO, so catch such cases here.  */
  if (relocation < 2)
      return bfd_reloc_outofrange;

  return _bfd_final_link_relocate (howto, abfd, input_section,
				   data, offset, symbol_value, addend);
}

/* Idea and code taken from elf32-d30v.  */
static bfd_reloc_status_type
pru_elf32_do_ldi32_relocate (bfd *abfd, reloc_howto_type *howto,
			     asection *input_section,
			     bfd_byte *data, bfd_vma offset,
			     bfd_vma symbol_value, bfd_vma addend)
{
  bfd_signed_vma relocation;
  bfd_size_type octets = offset * OCTETS_PER_BYTE (abfd, input_section);
  bfd_byte *location;
  unsigned long in1, in2;

  /* A hacked-up version of _bfd_final_link_relocate() follows.  */

  /* Sanity check the address.  */
  if (octets + bfd_get_reloc_size (howto)
      > bfd_get_section_limit_octets (abfd, input_section))
    return bfd_reloc_outofrange;

  /* This function assumes that we are dealing with a basic relocation
     against a symbol.  We want to compute the value of the symbol to
     relocate to.  This is just VALUE, the value of the symbol, plus
     ADDEND, any addend associated with the reloc.  */
  relocation = symbol_value + addend;

  BFD_ASSERT (!howto->pc_relative);

  /* A hacked-up version of _bfd_relocate_contents() follows.  */
  location = data + octets;

  BFD_ASSERT (!howto->pc_relative);

  in1 = bfd_get_32 (abfd, location);
  in2 = bfd_get_32 (abfd, location + 4);

  SET_INSN_FIELD (IMM16, in1, relocation >> 16);
  SET_INSN_FIELD (IMM16, in2, relocation & 0xffff);

  bfd_put_32 (abfd, in1, location);
  bfd_put_32 (abfd, in2, location + 4);

  /* Old GAS and LD versions have a bug, where the two
     LDI instructions are swapped.  Detect such object
     files and bail.  */
  if (GET_INSN_FIELD (RDSEL, in1) != RSEL_31_16)
    {
      /* xgettext:c-format */
      _bfd_error_handler (_("error: %pB: old incompatible object file detected"),
			  abfd);
      return bfd_reloc_notsupported;
    }

  return bfd_reloc_ok;
}

/* HOWTO handlers for relocations that require special handling.  */

static bfd_reloc_status_type
pru_elf32_pmem_relocate (bfd *abfd, arelent *reloc_entry,
			 asymbol *symbol, void *data,
			 asection *input_section, bfd *output_bfd,
			 char **error_message)
{
  /* If this is a relocatable link (output_bfd test tells us), just
     call the generic function.  Any adjustment will be done at final
     link time.  */
  if (output_bfd != NULL)
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
				  input_section, output_bfd, error_message);

  BFD_ASSERT (0);
  return pru_elf32_do_pmem_relocate (abfd, reloc_entry->howto,
				     input_section,
				     data, reloc_entry->address,
				     (symbol->value
				      + symbol->section->output_section->vma
				      + symbol->section->output_offset),
				     reloc_entry->addend);
}

static bfd_reloc_status_type
pru_elf32_s10_pcrel_relocate (bfd *abfd, arelent *reloc_entry,
				 asymbol *symbol, void *data,
				 asection *input_section, bfd *output_bfd,
				 char **error_message)
{
  /* If this is a relocatable link (output_bfd test tells us), just
     call the generic function.  Any adjustment will be done at final
     link time.  */
  if (output_bfd != NULL)
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
				  input_section, output_bfd, error_message);

  return pru_elf32_do_s10_pcrel_relocate (abfd, reloc_entry->howto,
					  input_section, data,
					  reloc_entry->address,
					  (symbol->value
					   + symbol->section->output_section->vma
					   + symbol->section->output_offset),
					  reloc_entry->addend);
}

static bfd_reloc_status_type
pru_elf32_u8_pcrel_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
			     void *data, asection *input_section,
			     bfd *output_bfd,
			     char **error_message)
{
  /* If this is a relocatable link (output_bfd test tells us), just
     call the generic function.  Any adjustment will be done at final
     link time.  */
  if (output_bfd != NULL)
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
				  input_section, output_bfd, error_message);

  return pru_elf32_do_u8_pcrel_relocate (abfd, reloc_entry->howto,
					 input_section,
					 data, reloc_entry->address,
					 (symbol->value
					  + symbol->section->output_section->vma
					  + symbol->section->output_offset),
					 reloc_entry->addend);
}

static bfd_reloc_status_type
pru_elf32_ldi32_relocate (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
			  void *data, asection *input_section,
			  bfd *output_bfd,
			  char **error_message)
{
  /* If this is a relocatable link (output_bfd test tells us), just
     call the generic function.  Any adjustment will be done at final
     link time.  */
  if (output_bfd != NULL)
    return bfd_elf_generic_reloc (abfd, reloc_entry, symbol, data,
				  input_section, output_bfd, error_message);

  return pru_elf32_do_ldi32_relocate (abfd, reloc_entry->howto,
				      input_section,
				      data, reloc_entry->address,
				      (symbol->value
				       + symbol->section->output_section->vma
				       + symbol->section->output_offset),
				      reloc_entry->addend);
}


/* Implement elf_backend_relocate_section.  */
static bfd_boolean
pru_elf32_relocate_section (bfd *output_bfd,
			    struct bfd_link_info *info,
			    bfd *input_bfd,
			    asection *input_section,
			    bfd_byte *contents,
			    Elf_Internal_Rela *relocs,
			    Elf_Internal_Sym *local_syms,
			    asection **local_sections)
{
  struct bfd_elf_section_data * esd = elf_section_data (input_section);
  Elf_Internal_Shdr *symtab_hdr;
  struct elf_link_hash_entry **sym_hashes;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;
  bfd_boolean is_rel_reloc;

  symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
  sym_hashes = elf_sym_hashes (input_bfd);
  relend = relocs + input_section->reloc_count;

  /* See if we have a REL type relocation.  */
  is_rel_reloc = (esd->rel.hdr != NULL);
  /* Sanity check - only one type of relocation per section.
     FIXME: Theoretically it is possible to have both types,
     but if that happens how can we distinguish between the two ?  */
  BFD_ASSERT (! is_rel_reloc || ! esd->rela.hdr);

  for (rel = relocs; rel < relend; rel++)
    {
      reloc_howto_type *howto;
      unsigned long r_symndx;
      Elf_Internal_Sym *sym;
      asection *sec;
      struct elf_link_hash_entry *h;
      bfd_vma relocation;
      bfd_reloc_status_type r = bfd_reloc_ok;
      const char *name = NULL;
      const char* msg = (const char*) NULL;
      bfd_boolean unresolved_reloc;
      bfd_vma addend;

      /* If we are using a REL relocation then the addend should be empty.  */
      BFD_ASSERT (! is_rel_reloc || rel->r_addend == 0);

      r_symndx = ELF32_R_SYM (rel->r_info);

      howto = lookup_howto ((unsigned) ELF32_R_TYPE (rel->r_info));
      h = NULL;
      sym = NULL;
      sec = NULL;

      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
	{
	  bfd_boolean warned, ignored;

	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
				   r_symndx, symtab_hdr, sym_hashes,
				   h, sec, relocation,
				   unresolved_reloc, warned, ignored);
	}

      if (sec && discarded_section (sec))
	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
					 rel, 1, relend, howto, 0, contents);

      /* Nothing more to do unless this is a final link.  */
      if (bfd_link_relocatable (info))
	continue;

      if (howto)
	{
	  switch (howto->type)
	    {
	    case R_PRU_NONE:
	      /* We don't need to find a value for this symbol.  It's just a
		 marker.  */
	      r = bfd_reloc_ok;
	      break;

	    case R_PRU_U16:
	      if (is_rel_reloc)
		{
		  unsigned long insn;
		  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
		  addend = GET_INSN_FIELD (IMM16, insn);
		}
	      else
		addend = rel->r_addend;
	      r = _bfd_final_link_relocate (howto, input_bfd,
					    input_section, contents,
					    rel->r_offset, relocation,
					    addend);
	      break;

	    case R_PRU_U16_PMEMIMM:
	    case R_PRU_32_PMEM:
	    case R_PRU_16_PMEM:
	      if (is_rel_reloc && howto->type == R_PRU_U16_PMEMIMM)
		{
		  unsigned long insn;
		  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
		  addend = GET_INSN_FIELD (IMM16, insn) << 2;
		}
	      else if (is_rel_reloc && howto->type == R_PRU_32_PMEM)
		{
		  addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
		  addend <<= 2;
		}
	      else if (is_rel_reloc && howto->type == R_PRU_16_PMEM)
		{
		  addend = bfd_get_16 (input_bfd, contents + rel->r_offset);
		  addend <<= 2;
		}
	      else
		{
		  BFD_ASSERT (!is_rel_reloc);
		  addend = rel->r_addend;
		}
	      r = pru_elf32_do_pmem_relocate (input_bfd, howto,
						input_section,
						contents, rel->r_offset,
						relocation, addend);
	      break;
	    case R_PRU_S10_PCREL:
	      BFD_ASSERT (! is_rel_reloc);
	      r = pru_elf32_do_s10_pcrel_relocate (input_bfd, howto,
						      input_section,
						      contents,
						      rel->r_offset,
						      relocation,
						      rel->r_addend);
	      break;
	    case R_PRU_U8_PCREL:
	      BFD_ASSERT (! is_rel_reloc);
	      r = pru_elf32_do_u8_pcrel_relocate (input_bfd, howto,
						      input_section,
						      contents,
						      rel->r_offset,
						      relocation,
						      rel->r_addend);
	      break;
	    case R_PRU_LDI32:
	      if (is_rel_reloc)
		{
		  unsigned long in1, in2;
		  in1 = bfd_get_32 (input_bfd, contents + rel->r_offset);
		  in2 = bfd_get_32 (input_bfd, contents + rel->r_offset + 4);
		  addend = (GET_INSN_FIELD (IMM16, in1) << 16)
			    | GET_INSN_FIELD (IMM16, in2);
		}
	      else
		{
		  addend = rel->r_addend;
		}
	      r = pru_elf32_do_ldi32_relocate (input_bfd, howto,
					       input_section,
					       contents,
					       rel->r_offset,
					       relocation,
					       addend);
	      break;
	    case R_PRU_GNU_DIFF8:
	    case R_PRU_GNU_DIFF16:
	    case R_PRU_GNU_DIFF32:
	    case R_PRU_GNU_DIFF16_PMEM:
	    case R_PRU_GNU_DIFF32_PMEM:
	      /* GNU extensions support only rela.  */
	      BFD_ASSERT (! is_rel_reloc);
	      /* Nothing to do here, as contents already contain the
		 diff value.  */
	      r = bfd_reloc_ok;
	      break;

	    case R_PRU_BFD_RELOC_16:
	      if (is_rel_reloc)
		addend = bfd_get_16 (input_bfd, contents + rel->r_offset);
	      else
		addend = rel->r_addend;
	      r = _bfd_final_link_relocate (howto, input_bfd,
					    input_section, contents,
					    rel->r_offset, relocation,
					    addend);
	      break;

	    case R_PRU_BFD_RELOC_32:
	      if (is_rel_reloc)
		addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
	      else
		addend = rel->r_addend;
	      r = _bfd_final_link_relocate (howto, input_bfd,
					    input_section, contents,
					    rel->r_offset, relocation,
					    addend);
	      break;

	    case R_PRU_GNU_BFD_RELOC_8:
	      BFD_ASSERT (! is_rel_reloc);
	      r = _bfd_final_link_relocate (howto, input_bfd,
					    input_section, contents,
					    rel->r_offset, relocation,
					    rel->r_addend);
	      break;

	    default:
	      BFD_ASSERT (0);
	      break;
	    }
	}
      else
	r = bfd_reloc_notsupported;

      if (r != bfd_reloc_ok)
	{
	  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 == NULL || *name == '\0')
		name = bfd_section_name (sec);
	    }

	  switch (r)
	    {
	    case bfd_reloc_overflow:
	      (*info->callbacks->reloc_overflow) (info, NULL, name,
						  howto->name, (bfd_vma) 0,
						  input_bfd, input_section,
						  rel->r_offset);
	      break;

	    case bfd_reloc_undefined:
	      (*info->callbacks->undefined_symbol) (info, name, input_bfd,
						    input_section,
						    rel->r_offset, TRUE);
	      break;

	    case bfd_reloc_outofrange:
	      if (msg == NULL)
		msg = _("relocation out of range");
	      break;

	    case bfd_reloc_notsupported:
	      if (msg == NULL)
		msg = _("unsupported relocation");
	      break;

	    case bfd_reloc_dangerous:
	      if (msg == NULL)
		msg = _("dangerous relocation");
	      break;

	    default:
	      if (msg == NULL)
		msg = _("unknown error");
	      break;
	    }

	  if (msg)
	    {
	      (*info->callbacks->warning) (info, msg, name, input_bfd,
					   input_section, rel->r_offset);
	      return FALSE;
	    }
	}
    }
  return TRUE;
}


/* Perform a diff relocation.  Nothing to do, as the difference value is
   already written into the section's contents.  */

static bfd_reloc_status_type
bfd_elf_pru_diff_relocate (bfd *abfd ATTRIBUTE_UNUSED,
			   arelent *reloc_entry ATTRIBUTE_UNUSED,
			   asymbol *symbol ATTRIBUTE_UNUSED,
			   void *data ATTRIBUTE_UNUSED,
			   asection *input_section ATTRIBUTE_UNUSED,
			   bfd *output_bfd ATTRIBUTE_UNUSED,
			   char **error_message ATTRIBUTE_UNUSED)
{
  return bfd_reloc_ok;
}


/* Returns whether the relocation type passed is a diff reloc.  */

static bfd_boolean
elf32_pru_is_diff_reloc (Elf_Internal_Rela *irel)
{
  return (ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF8
	  || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF16
	  || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF32
	  || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF16_PMEM
	  || ELF32_R_TYPE (irel->r_info) == R_PRU_GNU_DIFF32_PMEM);
}

/* Reduce the diff value written in the section by count if the shrinked
   insn address happens to fall between the two symbols for which this
   diff reloc was emitted.  */

static void
elf32_pru_adjust_diff_reloc_value (bfd *abfd,
				   struct bfd_section *isec,
				   Elf_Internal_Rela *irel,
				   bfd_vma symval,
				   bfd_vma shrinked_insn_address,
				   int count)
{
  unsigned char *reloc_contents = NULL;
  unsigned char *isec_contents = elf_section_data (isec)->this_hdr.contents;
  if (isec_contents == NULL)
  {
    if (! bfd_malloc_and_get_section (abfd, isec, &isec_contents))
      return;

    elf_section_data (isec)->this_hdr.contents = isec_contents;
  }

  reloc_contents = isec_contents + irel->r_offset;

  /* Read value written in object file.  */
  bfd_signed_vma x = 0;
  switch (ELF32_R_TYPE (irel->r_info))
  {
  case R_PRU_GNU_DIFF8:
    {
      x = bfd_get_signed_8 (abfd, reloc_contents);
      break;
    }
  case R_PRU_GNU_DIFF16:
    {
      x = bfd_get_signed_16 (abfd, reloc_contents);
      break;
    }
  case R_PRU_GNU_DIFF32:
    {
      x = bfd_get_signed_32 (abfd, reloc_contents);
      break;
    }
  case R_PRU_GNU_DIFF16_PMEM:
    {
      x = bfd_get_signed_16 (abfd, reloc_contents) * 4;
      break;
    }
  case R_PRU_GNU_DIFF32_PMEM:
    {
      x = bfd_get_signed_32 (abfd, reloc_contents) * 4;
      break;
    }
  default:
    {
      BFD_FAIL ();
    }
  }

  /* For a diff reloc sym1 - sym2 the diff at assembly time (x) is written
     into the object file at the reloc offset.  sym2's logical value is
     symval (<start_of_section>) + reloc addend.  Compute the start and end
     addresses and check if the shrinked insn falls between sym1 and sym2.  */

  bfd_vma end_address = symval + irel->r_addend;
  bfd_vma start_address = end_address - x;

  /* Shrink the absolute DIFF value (get the to labels "closer"
     together), because we have removed data between labels.  */
  if (x < 0)
    {
      x += count;
      /* In case the signed x is negative, restore order.  */
      SWAP_VALS (end_address, start_address);
    }
  else
    {
      x -= count;
    }

  /* Reduce the diff value by count bytes and write it back into section
    contents.  */

  if (shrinked_insn_address >= start_address
      && shrinked_insn_address <= end_address)
  {
    switch (ELF32_R_TYPE (irel->r_info))
    {
    case R_PRU_GNU_DIFF8:
      {
	bfd_put_signed_8 (abfd, x & 0xFF, reloc_contents);
	break;
      }
    case R_PRU_GNU_DIFF16:
      {
	bfd_put_signed_16 (abfd, x & 0xFFFF, reloc_contents);
	break;
      }
    case R_PRU_GNU_DIFF32:
      {
	bfd_put_signed_32 (abfd, x & 0xFFFFFFFF, reloc_contents);
	break;
      }
    case R_PRU_GNU_DIFF16_PMEM:
      {
	bfd_put_signed_16 (abfd, (x / 4) & 0xFFFF, reloc_contents);
	break;
      }
    case R_PRU_GNU_DIFF32_PMEM:
      {
	bfd_put_signed_32 (abfd, (x / 4) & 0xFFFFFFFF, reloc_contents);
	break;
      }
    default:
      {
	BFD_FAIL ();
      }
    }

  }
}

/* Delete some bytes from a section while changing the size of an instruction.
   The parameter "addr" denotes the section-relative offset pointing just
   behind the shrinked instruction. "addr+count" point at the first
   byte just behind the original unshrinked instruction.

   Idea copied from the AVR port.  */

static bfd_boolean
pru_elf_relax_delete_bytes (bfd *abfd,
			    asection *sec,
			    bfd_vma addr,
			    int count)
{
  Elf_Internal_Shdr *symtab_hdr;
  unsigned int sec_shndx;
  bfd_byte *contents;
  Elf_Internal_Rela *irel, *irelend;
  Elf_Internal_Sym *isym;
  Elf_Internal_Sym *isymbuf = NULL;
  bfd_vma toaddr;
  struct elf_link_hash_entry **sym_hashes;
  struct elf_link_hash_entry **end_hashes;
  unsigned int symcount;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
  contents = elf_section_data (sec)->this_hdr.contents;

  toaddr = sec->size;

  irel = elf_section_data (sec)->relocs;
  irelend = irel + sec->reloc_count;

  /* Actually delete the bytes.  */
  if (toaddr - addr - count > 0)
    memmove (contents + addr, contents + addr + count,
	     (size_t) (toaddr - addr - count));
  sec->size -= count;

  /* Adjust all the reloc addresses.  */
  for (irel = elf_section_data (sec)->relocs; irel < irelend; irel++)
    {
      bfd_vma old_reloc_address;

      old_reloc_address = (sec->output_section->vma
			   + sec->output_offset + irel->r_offset);

      /* Get the new reloc address.  */
      if ((irel->r_offset > addr
	   && irel->r_offset < toaddr))
	{
	  if (debug_relax)
	    printf ("Relocation at address 0x%x needs to be moved.\n"
		    "Old section offset: 0x%x, New section offset: 0x%x \n",
		    (unsigned int) old_reloc_address,
		    (unsigned int) irel->r_offset,
		    (unsigned int) ((irel->r_offset) - count));

	  irel->r_offset -= count;
	}

    }

   /* The reloc's own addresses are now ok.  However, we need to readjust
      the reloc's addend, i.e. the reloc's value if two conditions are met:
      1.) the reloc is relative to a symbol in this section that
	  is located in front of the shrinked instruction
      2.) symbol plus addend end up behind the shrinked instruction.

      The most common case where this happens are relocs relative to
      the section-start symbol.

      This step needs to be done for all of the sections of the bfd.  */

  {
    struct bfd_section *isec;

    for (isec = abfd->sections; isec; isec = isec->next)
     {
       bfd_vma symval;
       bfd_vma shrinked_insn_address;

       if (isec->reloc_count == 0)
	 continue;

       shrinked_insn_address = (sec->output_section->vma
				+ sec->output_offset + addr);

       irel = elf_section_data (isec)->relocs;
       /* PR 12161: Read in the relocs for this section if necessary.  */
       if (irel == NULL)
	 irel = _bfd_elf_link_read_relocs (abfd, isec, NULL, NULL, TRUE);

       for (irelend = irel + isec->reloc_count;
	    irel < irelend;
	    irel++)
	 {
	   /* Read this BFD's local symbols if we haven't done
	      so already.  */
	   if (isymbuf == NULL && symtab_hdr->sh_info != 0)
	     {
	       isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
	       if (isymbuf == NULL)
		 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
						 symtab_hdr->sh_info, 0,
						 NULL, NULL, NULL);
	       if (isymbuf == NULL)
		 return FALSE;
	     }

	   /* Get the value of the symbol referred to by the reloc.  */
	   if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
	     {
	       /* A local symbol.  */
	       asection *sym_sec;

	       isym = isymbuf + ELF32_R_SYM (irel->r_info);
	       sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
	       symval = isym->st_value;
	       /* If the reloc is absolute, it will not have
		  a symbol or section associated with it.  */
	       if (sym_sec == sec)
		 {
		   symval += sym_sec->output_section->vma
		     + sym_sec->output_offset;

		   if (debug_relax)
		     printf ("Checking if the relocation's "
			     "addend needs corrections.\n"
			     "Address of anchor symbol: 0x%x \n"
			     "Address of relocation target: 0x%x \n"
			     "Address of relaxed insn: 0x%x \n",
			     (unsigned int) symval,
			     (unsigned int) (symval + irel->r_addend),
			     (unsigned int) shrinked_insn_address);

		   /* Shrink the special DIFF relocations.  */
		   if (elf32_pru_is_diff_reloc (irel))
		     {
		       elf32_pru_adjust_diff_reloc_value (abfd, isec, irel,
							  symval,
							  shrinked_insn_address,
							  count);
		     }

		   /* Fix the addend, if it is affected.  */
		   if (symval <= shrinked_insn_address
		       && (symval + irel->r_addend) > shrinked_insn_address)
		     {

		       irel->r_addend -= count;

		       if (debug_relax)
			 printf ("Relocation's addend needed to be fixed \n");
		     }
		 }
	       /* else...Reference symbol is absolute.
		  No adjustment needed.  */
	     }
	   /* else...Reference symbol is extern.  No need for adjusting
	      the addend.  */
	 }
     }
  }

  /* Adjust the local symbols defined in this section.  */
  isym = (Elf_Internal_Sym *) symtab_hdr->contents;
  /* Fix PR 9841, there may be no local symbols.  */
  if (isym != NULL)
    {
      Elf_Internal_Sym *isymend;

      isymend = isym + symtab_hdr->sh_info;
      for (; isym < isymend; isym++)
	{
	  if (isym->st_shndx == sec_shndx)
	    {
	      if (isym->st_value > addr
		  && isym->st_value <= toaddr)
		isym->st_value -= count;

	      if (isym->st_value <= addr
		  && isym->st_value + isym->st_size > addr)
		{
		  /* If this assert fires then we have a symbol that ends
		     part way through an instruction.  Does that make
		     sense?  */
		  BFD_ASSERT (isym->st_value + isym->st_size >= addr + count);
		  isym->st_size -= count;
		}
	    }
	}
    }

  /* Now adjust the global symbols defined in this section.  */
  symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
	      - symtab_hdr->sh_info);
  sym_hashes = elf_sym_hashes (abfd);
  end_hashes = sym_hashes + symcount;
  for (; sym_hashes < end_hashes; sym_hashes++)
    {
      struct elf_link_hash_entry *sym_hash = *sym_hashes;
      if ((sym_hash->root.type == bfd_link_hash_defined
	   || sym_hash->root.type == bfd_link_hash_defweak)
	  && sym_hash->root.u.def.section == sec)
	{
	  if (sym_hash->root.u.def.value > addr
	      && sym_hash->root.u.def.value <= toaddr)
	    sym_hash->root.u.def.value -= count;

	  if (sym_hash->root.u.def.value <= addr
	      && (sym_hash->root.u.def.value + sym_hash->size > addr))
	    {
	      /* If this assert fires then we have a symbol that ends
		 part way through an instruction.  Does that make
		 sense?  */
	      BFD_ASSERT (sym_hash->root.u.def.value + sym_hash->size
			  >= addr + count);
	      sym_hash->size -= count;
	    }
	}
    }

  return TRUE;
}

static bfd_boolean
pru_elf32_relax_section (bfd * abfd, asection * sec,
			  struct bfd_link_info * link_info,
			  bfd_boolean * again)
{
  Elf_Internal_Shdr * symtab_hdr;
  Elf_Internal_Rela * internal_relocs;
  Elf_Internal_Rela * irel;
  Elf_Internal_Rela * irelend;
  bfd_byte *	      contents = NULL;
  Elf_Internal_Sym *  isymbuf = NULL;

  /* Assume nothing changes.  */
  *again = FALSE;

  /* We don't have to do anything for a relocatable link, if
     this section does not have relocs, or if this is not a
     code section.  */
  if (bfd_link_relocatable (link_info)
    || (sec->flags & SEC_RELOC) == 0
    || sec->reloc_count == 0 || (sec->flags & SEC_CODE) == 0)
    return TRUE;

  symtab_hdr = & elf_tdata (abfd)->symtab_hdr;

  /* Get a copy of the native relocations.  */
  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
					       link_info->keep_memory);
  if (internal_relocs == NULL)
    goto error_return;

  /* Walk through them looking for relaxing opportunities.  */
  irelend = internal_relocs + sec->reloc_count;

  for (irel = internal_relocs; irel < irelend; irel++)
    {
      bfd_vma symval;

      /* Get the section contents if we haven't done so already.  */
      if (contents == NULL)
	{
	  /* Get cached copy if it exists.  */
	  if (elf_section_data (sec)->this_hdr.contents != NULL)
	    contents = elf_section_data (sec)->this_hdr.contents;
	  else if (! bfd_malloc_and_get_section (abfd, sec, &contents))
	    goto error_return;
	}

      /* Read this BFD's local symbols if we haven't done so already.  */
      if (isymbuf == NULL && symtab_hdr->sh_info != 0)
	{
	  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
	  if (isymbuf == NULL)
	    isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
					    symtab_hdr->sh_info, 0,
					    NULL, NULL, NULL);
	  if (isymbuf == NULL)
	    goto error_return;
	}

      /* Get the value of the symbol referred to by the reloc.  */
      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
	{
	  /* A local symbol.  */
	  Elf_Internal_Sym *isym;
	  asection *sym_sec;

	  isym = isymbuf + ELF32_R_SYM (irel->r_info);
	  if (isym->st_shndx == SHN_UNDEF)
	    sym_sec = bfd_und_section_ptr;
	  else if (isym->st_shndx == SHN_ABS)
	    sym_sec = bfd_abs_section_ptr;
	  else if (isym->st_shndx == SHN_COMMON)
	    sym_sec = bfd_com_section_ptr;
	  else
	    sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
	  symval = (isym->st_value
		    + sym_sec->output_section->vma + sym_sec->output_offset);
	}
      else
	{
	  unsigned long indx;
	  struct elf_link_hash_entry *h;

	  /* An external symbol.  */
	  indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
	  h = elf_sym_hashes (abfd)[indx];
	  BFD_ASSERT (h != NULL);

	  if (h->root.type != bfd_link_hash_defined
	      && h->root.type != bfd_link_hash_defweak)
	    /* This appears to be a reference to an undefined
	       symbol.  Just ignore it--it will be caught by the
	       regular reloc processing.  */
	    continue;

	  symval = (h->root.u.def.value
		    + h->root.u.def.section->output_section->vma
		    + h->root.u.def.section->output_offset);
	}

      /* For simplicity of coding, we are going to modify the section
	 contents, the section relocs, and the BFD symbol table.  We
	 must tell the rest of the code not to free up this
	 information.  It would be possible to instead create a table
	 of changes which have to be made, as is done in coff-mips.c;
	 that would be more work, but would require less memory when
	 the linker is run.  */

      /* Check if we can remove an LDI instruction from the LDI32
	 pseudo instruction if the upper 16 operand bits are zero.  */
      if (ELF32_R_TYPE (irel->r_info) == (int) R_PRU_LDI32)
	{
	  bfd_vma value = symval + irel->r_addend;

	  if (debug_relax)
	    printf ("R_PRU_LDI32 with value=0x%lx\n", (long) value);

	  if ((long) value >> 16 == 0)
	    {
	      unsigned long insn;

	      /* Note that we've changed the relocs, section contents.  */
	      elf_section_data (sec)->relocs = internal_relocs;
	      elf_section_data (sec)->this_hdr.contents = contents;
	      symtab_hdr->contents = (unsigned char *) isymbuf;

	      /* Make the second instruction load the 16-bit constant
		 into the full 32-bit register.  */
	      insn = bfd_get_32 (abfd, contents + irel->r_offset + 4);

	      /* Old GAS and LD versions have a bug, where the two
		 LDI instructions are swapped.  Detect such object
		 files and bail.  */
	      if (GET_INSN_FIELD (RDSEL, insn) != RSEL_15_0)
		{
		  /* xgettext:c-format */
		  _bfd_error_handler (_("error: %pB: old incompatible object file detected"),
				      abfd);
		  goto error_return;
		}

	      SET_INSN_FIELD (RDSEL, insn, RSEL_31_0);
	      bfd_put_32 (abfd, insn, contents + irel->r_offset + 4);

	      /* Delete the first LDI instruction.  Note that there should
		 be no relocations or symbols pointing to the second LDI
		 instruction.  */
	      if (!pru_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 4))
		goto error_return;

	      /* We're done with deletion of the first instruction.
		 Set a regular LDI relocation for the second instruction
		 we left to load the 16-bit value into the 32-bit
		 register.  */
	      irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
					   R_PRU_U16);

	      /* That will change things, so, we should relax again.
		 Note that this is not required, and it may be slow.  */
	      *again = TRUE;
	    }
	}
    }

  if (isymbuf != NULL && symtab_hdr->contents != (unsigned char *) isymbuf)
    {
      if (!link_info->keep_memory)
	free (isymbuf);
      else
	{
	  /* Cache the symbols for elf_link_input_bfd.  */
	  symtab_hdr->contents = (unsigned char *) isymbuf;
	}
    }

  if (contents != NULL
      && elf_section_data (sec)->this_hdr.contents != contents)
    {
      if (!link_info->keep_memory)
	free (contents);
      else
	{
	  /* Cache the section contents for elf_link_input_bfd.  */
	  elf_section_data (sec)->this_hdr.contents = contents;
	}
    }

  if (elf_section_data (sec)->relocs != internal_relocs)
    free (internal_relocs);

  return TRUE;

 error_return:
  if (symtab_hdr->contents != (unsigned char *) isymbuf)
    free (isymbuf);
  if (elf_section_data (sec)->this_hdr.contents != contents)
    free (contents);
  if (elf_section_data (sec)->relocs != internal_relocs)
    free (internal_relocs);

  return FALSE;
}

/* Free the derived linker hash table.  */
static void
pru_elf32_link_hash_table_free (bfd *obfd)
{
  _bfd_elf_link_hash_table_free (obfd);
}

/* Implement bfd_elf32_bfd_link_hash_table_create.  */
static struct bfd_link_hash_table *
pru_elf32_link_hash_table_create (bfd *abfd)
{
  struct elf_link_hash_table *ret;
  size_t amt = sizeof (struct elf_link_hash_table);

  ret = bfd_zmalloc (amt);
  if (ret == NULL)
    return NULL;

  if (!_bfd_elf_link_hash_table_init (ret, abfd,
				      link_hash_newfunc,
				      sizeof (struct
					      elf_link_hash_entry),
				      PRU_ELF_DATA))
    {
      free (ret);
      return NULL;
    }

  ret->root.hash_table_free = pru_elf32_link_hash_table_free;

  return &ret->root;
}

#define ELF_ARCH			bfd_arch_pru
#define ELF_TARGET_ID			PRU_ELF_DATA
#define ELF_MACHINE_CODE		EM_TI_PRU

#define ELF_MAXPAGESIZE			1

#define bfd_elf32_bfd_link_hash_table_create \
					  pru_elf32_link_hash_table_create

/* Relocation table lookup macros.  */

#define bfd_elf32_bfd_reloc_type_lookup	  pru_elf32_bfd_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup	  pru_elf32_bfd_reloc_name_lookup

#define elf_info_to_howto		pru_elf32_info_to_howto
#define elf_info_to_howto_rel		NULL

/* elf backend functions.  */

/* TI folks like to use a mix of REL and RELA relocations.  See also
   the MSP430 and TI C6X backends.  */
#define elf_backend_may_use_rel_p  1
#define elf_backend_may_use_rela_p 1
#define elf_backend_default_use_rela_p 1

#define elf_backend_rela_normal		1

#define elf_backend_relocate_section	pru_elf32_relocate_section
#define bfd_elf32_bfd_relax_section	pru_elf32_relax_section

#define TARGET_LITTLE_SYM		pru_elf32_vec
#define TARGET_LITTLE_NAME		"elf32-pru"

#include "elf32-target.h"
