/* Ubicom IP2xxx specific support for 32-bit ELF
   Copyright (C) 2000-2015 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 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.  */

#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/ip2k.h"

/* Struct used to pass miscellaneous paramaters which
   helps to avoid overly long parameter lists.  */
struct misc
{
  Elf_Internal_Shdr *  symtab_hdr;
  Elf_Internal_Rela *  irelbase;
  bfd_byte *           contents;
  Elf_Internal_Sym *   isymbuf;
};

struct ip2k_opcode
{
  unsigned short opcode;
  unsigned short mask;
};

static bfd_boolean ip2k_relaxed = FALSE;

static const struct ip2k_opcode ip2k_page_opcode[] =
{
  {0x0010, 0xFFF8},	/* Page.  */
  {0x0000, 0x0000},
};

#define IS_PAGE_OPCODE(code) \
  ip2k_is_opcode (code, ip2k_page_opcode)

static const struct ip2k_opcode ip2k_jmp_opcode[] =
{
  {0xE000, 0xE000},	/* Jmp.  */
  {0x0000, 0x0000},
};

#define IS_JMP_OPCODE(code) \
  ip2k_is_opcode (code, ip2k_jmp_opcode)

static const struct ip2k_opcode ip2k_snc_opcode[] =
{
  {0xA00B, 0xFFFF},	/* Snc.  */
  {0x0000, 0x0000},
};

#define IS_SNC_OPCODE(code) \
  ip2k_is_opcode (code, ip2k_snc_opcode)

static const struct ip2k_opcode ip2k_inc_1sp_opcode[] =
{
  {0x2B81, 0xFFFF},	/* Inc 1(SP).  */
  {0x0000, 0x0000},
};

#define IS_INC_1SP_OPCODE(code) \
  ip2k_is_opcode (code, ip2k_inc_1sp_opcode)

static const struct ip2k_opcode ip2k_add_2sp_w_opcode[] =
{
  {0x1F82, 0xFFFF},	/* Add 2(SP),w.  */
  {0x0000, 0x0000},
};

#define IS_ADD_2SP_W_OPCODE(code) \
  ip2k_is_opcode (code, ip2k_add_2sp_w_opcode)

static const struct ip2k_opcode ip2k_add_w_wreg_opcode[] =
{
  {0x1C0A, 0xFFFF},	/* Add w,wreg.  */
  {0x1E0A, 0xFFFF},	/* Add wreg,w.  */
  {0x0000, 0x0000},
};

#define IS_ADD_W_WREG_OPCODE(code) \
  ip2k_is_opcode (code, ip2k_add_w_wreg_opcode)

static const struct ip2k_opcode ip2k_add_pcl_w_opcode[] =
{
  {0x1E09, 0xFFFF},	/* Add pcl,w.  */
  {0x0000, 0x0000},
};

#define IS_ADD_PCL_W_OPCODE(code) \
  ip2k_is_opcode (code, ip2k_add_pcl_w_opcode)

static const struct ip2k_opcode ip2k_skip_opcodes[] =
{
  {0xB000, 0xF000},	/* sb */
  {0xA000, 0xF000},	/* snb */
  {0x7600, 0xFE00},	/* cse/csne #lit */
  {0x5800, 0xFC00},	/* incsnz */
  {0x4C00, 0xFC00},	/* decsnz */
  {0x4000, 0xFC00},	/* cse/csne */
  {0x3C00, 0xFC00},	/* incsz */
  {0x2C00, 0xFC00},	/* decsz */
  {0x0000, 0x0000},
};

#define IS_SKIP_OPCODE(code) \
  ip2k_is_opcode (code, ip2k_skip_opcodes)

/* Relocation tables.  */
static reloc_howto_type ip2k_elf_howto_table [] =
{
#define IP2K_HOWTO(t,rs,s,bs,pr,bp,name,sm,dm) \
    HOWTO(t,                    /* type */ \
          rs,                   /* rightshift */ \
          s,                    /* size (0 = byte, 1 = short, 2 = long) */ \
          bs,                   /* bitsize */ \
          pr,                   /* pc_relative */ \
          bp,                   /* bitpos */ \
          complain_overflow_dont,/* complain_on_overflow */ \
          bfd_elf_generic_reloc,/* special_function */ \
          name,                 /* name */ \
          FALSE,                /* partial_inplace */ \
          sm,                   /* src_mask */ \
          dm,                   /* dst_mask */ \
          pr)                   /* pcrel_offset */

  /* This reloc does nothing.  */
  IP2K_HOWTO (R_IP2K_NONE, 0,3,0, FALSE, 0, "R_IP2K_NONE", 0, 0),
  /* A 16 bit absolute relocation.  */
  IP2K_HOWTO (R_IP2K_16, 0,1,16, FALSE, 0, "R_IP2K_16", 0, 0xffff),
  /* A 32 bit absolute relocation.  */
  IP2K_HOWTO (R_IP2K_32, 0,2,32, FALSE, 0, "R_IP2K_32", 0, 0xffffffff),
  /* A 8-bit data relocation for the FR9 field.  Ninth bit is computed specially.  */
  IP2K_HOWTO (R_IP2K_FR9, 0,1,9, FALSE, 0, "R_IP2K_FR9", 0, 0x00ff),
  /* A 4-bit data relocation.  */
  IP2K_HOWTO (R_IP2K_BANK, 8,1,4, FALSE, 0, "R_IP2K_BANK", 0, 0x000f),
  /* A 13-bit insn relocation - word address => right-shift 1 bit extra.  */
  IP2K_HOWTO (R_IP2K_ADDR16CJP, 1,1,13, FALSE, 0, "R_IP2K_ADDR16CJP", 0, 0x1fff),
  /* A 3-bit insn relocation - word address => right-shift 1 bit extra.  */
  IP2K_HOWTO (R_IP2K_PAGE3, 14,1,3, FALSE, 0, "R_IP2K_PAGE3", 0, 0x0007),
  /* Two 8-bit data relocations.  */
  IP2K_HOWTO (R_IP2K_LO8DATA, 0,1,8, FALSE, 0, "R_IP2K_LO8DATA", 0, 0x00ff),
  IP2K_HOWTO (R_IP2K_HI8DATA, 8,1,8, FALSE, 0, "R_IP2K_HI8DATA", 0, 0x00ff),
  /* Two 8-bit insn relocations.  word address => right-shift 1 bit extra.  */
  IP2K_HOWTO (R_IP2K_LO8INSN, 1,1,8, FALSE, 0, "R_IP2K_LO8INSN", 0, 0x00ff),
  IP2K_HOWTO (R_IP2K_HI8INSN, 9,1,8, FALSE, 0, "R_IP2K_HI8INSN", 0, 0x00ff),

  /* Special 1 bit relocation for SKIP instructions.  */
  IP2K_HOWTO (R_IP2K_PC_SKIP, 1,1,1, FALSE, 12, "R_IP2K_PC_SKIP", 0xfffe, 0x1000),
  /* 16 bit word address.  */
  IP2K_HOWTO (R_IP2K_TEXT, 1,1,16, FALSE, 0, "R_IP2K_TEXT", 0, 0xffff),
  /* A 7-bit offset relocation for the FR9 field.  Eigth and ninth bit comes from insn.  */
  IP2K_HOWTO (R_IP2K_FR_OFFSET, 0,1,9, FALSE, 0, "R_IP2K_FR_OFFSET", 0x180, 0x007f),
  /* Bits 23:16 of an address.  */
  IP2K_HOWTO (R_IP2K_EX8DATA, 16,1,8, FALSE, 0, "R_IP2K_EX8DATA", 0, 0x00ff),
};


/* Map BFD reloc types to IP2K ELF reloc types.  */

static reloc_howto_type *
ip2k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
			bfd_reloc_code_real_type code)
{
  /* Note that the ip2k_elf_howto_table is indxed by the R_
     constants.  Thus, the order that the howto records appear in the
     table *must* match the order of the relocation types defined in
     include/elf/ip2k.h.  */

  switch (code)
    {
    case BFD_RELOC_NONE:
      return &ip2k_elf_howto_table[ (int) R_IP2K_NONE];
    case BFD_RELOC_16:
      return &ip2k_elf_howto_table[ (int) R_IP2K_16];
    case BFD_RELOC_32:
      return &ip2k_elf_howto_table[ (int) R_IP2K_32];
    case BFD_RELOC_IP2K_FR9:
      return &ip2k_elf_howto_table[ (int) R_IP2K_FR9];
    case BFD_RELOC_IP2K_BANK:
      return &ip2k_elf_howto_table[ (int) R_IP2K_BANK];
    case BFD_RELOC_IP2K_ADDR16CJP:
      return &ip2k_elf_howto_table[ (int) R_IP2K_ADDR16CJP];
    case BFD_RELOC_IP2K_PAGE3:
      return &ip2k_elf_howto_table[ (int) R_IP2K_PAGE3];
    case BFD_RELOC_IP2K_LO8DATA:
      return &ip2k_elf_howto_table[ (int) R_IP2K_LO8DATA];
    case BFD_RELOC_IP2K_HI8DATA:
      return &ip2k_elf_howto_table[ (int) R_IP2K_HI8DATA];
    case BFD_RELOC_IP2K_LO8INSN:
      return &ip2k_elf_howto_table[ (int) R_IP2K_LO8INSN];
    case BFD_RELOC_IP2K_HI8INSN:
      return &ip2k_elf_howto_table[ (int) R_IP2K_HI8INSN];
    case BFD_RELOC_IP2K_PC_SKIP:
      return &ip2k_elf_howto_table[ (int) R_IP2K_PC_SKIP];
    case BFD_RELOC_IP2K_TEXT:
      return &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
    case BFD_RELOC_IP2K_FR_OFFSET:
      return &ip2k_elf_howto_table[ (int) R_IP2K_FR_OFFSET];
    case BFD_RELOC_IP2K_EX8DATA:
      return &ip2k_elf_howto_table[ (int) R_IP2K_EX8DATA];
    default:
      /* Pacify gcc -Wall.  */
      return NULL;
    }
  return NULL;
}

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

  for (i = 0;
       i < sizeof (ip2k_elf_howto_table) / sizeof (ip2k_elf_howto_table[0]);
       i++)
    if (ip2k_elf_howto_table[i].name != NULL
	&& strcasecmp (ip2k_elf_howto_table[i].name, r_name) == 0)
      return &ip2k_elf_howto_table[i];

  return NULL;
}

static void
ip2k_get_mem (bfd *abfd ATTRIBUTE_UNUSED,
	      bfd_byte *addr,
	      int length,
	      bfd_byte *ptr)
{
  while (length --)
    * ptr ++ = bfd_get_8 (abfd, addr ++);
}

static bfd_boolean
ip2k_is_opcode (bfd_byte *code, const struct ip2k_opcode *opcodes)
{
  unsigned short insn = (code[0] << 8) | code[1];

  while (opcodes->mask != 0)
    {
      if ((insn & opcodes->mask) == opcodes->opcode)
	return TRUE;

      opcodes ++;
    }

  return FALSE;
}

#define PAGENO(ABSADDR) ((ABSADDR) & 0xFFFFC000)
#define BASEADDR(SEC)	((SEC)->output_section->vma + (SEC)->output_offset)

#define UNDEFINED_SYMBOL (~(bfd_vma)0)

/* Return the value of the symbol associated with the relocation IREL.  */

static bfd_vma
symbol_value (bfd *abfd,
	      Elf_Internal_Shdr *symtab_hdr,
	      Elf_Internal_Sym *isymbuf,
	      Elf_Internal_Rela *irel)
{
  if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    {
      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);

      return isym->st_value + BASEADDR (sym_sec);
    }
  else
    {
      unsigned long indx;
      struct elf_link_hash_entry *h;

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

      return (h->root.u.def.value + BASEADDR (h->root.u.def.section));
    }
}

/* Determine if the instruction sequence matches that for
   the prologue of a switch dispatch table with fewer than
   128 entries.

          sc
          page    $nnn0
          jmp     $nnn0
          add     w,wreg
          add     pcl,w
  addr=>
          page    $nnn1
          jmp     $nnn1
 	   page    $nnn2
 	   jmp     $nnn2
 	   ...
 	   page    $nnnN
 	   jmp     $nnnN

  After relaxation.
  	   sc
 	   page    $nnn0
  	   jmp     $nnn0
 	   add     pcl,w
  addr=>
  	   jmp     $nnn1
 	   jmp     $nnn2
 	   ...
          jmp     $nnnN  */

static int
ip2k_is_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
			  asection *sec,
			  bfd_vma addr,
			  bfd_byte *contents)
{
  bfd_byte code[4];
  int table_index = 0;

  /* Check current page-jmp.  */
  if (addr + 4 > sec->size)
    return -1;

  ip2k_get_mem (abfd, contents + addr, 4, code);

  if ((! IS_PAGE_OPCODE (code + 0))
      || (! IS_JMP_OPCODE (code + 2)))
    return -1;

  /* Search back.  */
  while (1)
    {
      if (addr < 4)
	return -1;

      /* Check previous 2 instructions.  */
      ip2k_get_mem (abfd, contents + addr - 4, 4, code);
      if ((IS_ADD_W_WREG_OPCODE (code + 0))
	  && (IS_ADD_PCL_W_OPCODE (code + 2)))
	return table_index;

      if ((! IS_PAGE_OPCODE (code + 0))
	  || (! IS_JMP_OPCODE (code + 2)))
	return -1;

      table_index++;
      addr -= 4;
    }
}

/* Determine if the instruction sequence matches that for
   the prologue switch dispatch table with fewer than
   256 entries but more than 127.

   Before relaxation.
          push    %lo8insn(label) ; Push address of table
          push    %hi8insn(label)
          add     w,wreg          ; index*2 => offset
          snc                     ; CARRY SET?
          inc     1(sp)           ; Propagate MSB into table address
          add     2(sp),w         ; Add low bits of offset to table address
          snc                     ; and handle any carry-out
          inc     1(sp)
   addr=>
          page    __indjmp        ; Do an indirect jump to that location
          jmp     __indjmp
   label:                         ; case dispatch table starts here
 	   page    $nnn1
 	   jmp	   $nnn1
 	   page	   $nnn2
 	   jmp     $nnn2
 	   ...
 	   page    $nnnN
 	   jmp	   $nnnN

  After relaxation.
          push    %lo8insn(label) ; Push address of table
          push    %hi8insn(label)
          add     2(sp),w         ; Add low bits of offset to table address
          snc                     ; and handle any carry-out
          inc     1(sp)
  addr=>
          page    __indjmp        ; Do an indirect jump to that location
          jmp     __indjmp
   label:                         ; case dispatch table starts here
          jmp     $nnn1
          jmp     $nnn2
          ...
          jmp     $nnnN  */

static int
ip2k_is_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
			  asection *sec,
			  bfd_vma addr,
			  bfd_byte *contents)
{
  bfd_byte code[16];
  int table_index = 0;

  /* Check current page-jmp.  */
  if (addr + 4 > sec->size)
    return -1;

  ip2k_get_mem (abfd, contents + addr, 4, code);
  if ((! IS_PAGE_OPCODE (code + 0))
      || (! IS_JMP_OPCODE (code + 2)))
    return -1;

  /* Search back.  */
  while (1)
    {
      if (addr < 16)
	return -1;

      /* Check previous 8 instructions.  */
      ip2k_get_mem (abfd, contents + addr - 16, 16, code);
      if ((IS_ADD_W_WREG_OPCODE (code + 0))
	  && (IS_SNC_OPCODE (code + 2))
	  && (IS_INC_1SP_OPCODE (code + 4))
	  && (IS_ADD_2SP_W_OPCODE (code + 6))
	  && (IS_SNC_OPCODE (code + 8))
	  && (IS_INC_1SP_OPCODE (code + 10))
	  && (IS_PAGE_OPCODE (code + 12))
	  && (IS_JMP_OPCODE (code + 14)))
	return table_index;

      if ((IS_ADD_W_WREG_OPCODE (code + 2))
	  && (IS_SNC_OPCODE (code + 4))
	  && (IS_INC_1SP_OPCODE (code + 6))
	  && (IS_ADD_2SP_W_OPCODE (code + 8))
	  && (IS_SNC_OPCODE (code + 10))
	  && (IS_INC_1SP_OPCODE (code + 12))
	  && (IS_JMP_OPCODE (code + 14)))
	return table_index;

      if ((! IS_PAGE_OPCODE (code + 0))
	  || (! IS_JMP_OPCODE (code + 2)))
	return -1;

      table_index++;
      addr -= 4;
    }
}

/* Returns the expected page state for the given instruction not including
   the effect of page instructions.  */

static bfd_vma
ip2k_nominal_page_bits (bfd *abfd ATTRIBUTE_UNUSED,
			asection *sec,
			bfd_vma addr,
			bfd_byte *contents)
{
  bfd_vma page = PAGENO (BASEADDR (sec) + addr);

  /* Check if section flows into this page. If not then the page
     bits are assumed to match the PC. This will be true unless
     the user has a page instruction without a call/jump, in which
     case they are on their own.  */
  if (PAGENO (BASEADDR (sec)) == page)
    return page;

  /* Section flows across page boundary. The page bits should match
     the PC unless there is a possible flow from the previous page,
     in which case it is not possible to determine the value of the
     page bits.  */
  while (PAGENO (BASEADDR (sec) + addr - 2) == page)
    {
      bfd_byte code[2];

      addr -= 2;
      ip2k_get_mem (abfd, contents + addr, 2, code);
      if (!IS_PAGE_OPCODE (code))
	continue;

      /* Found a page instruction, check if jump table.  */
      if (ip2k_is_switch_table_128 (abfd, sec, addr, contents) != -1)
	/* Jump table => page is conditional.  */
	continue;

      if (ip2k_is_switch_table_256 (abfd, sec, addr, contents) != -1)
	/* Jump table => page is conditional.  */
	continue;

      /* Found a page instruction, check if conditional.  */
      if (addr >= 2)
        {
	  ip2k_get_mem (abfd, contents + addr - 2, 2, code);
          if (IS_SKIP_OPCODE (code))
	    /* Page is conditional.  */
	    continue;
        }

      /* Unconditional page instruction => page bits should be correct.  */
      return page;
    }

  /* Flow from previous page => page bits are impossible to determine.  */
  return 0;
}

static bfd_boolean
ip2k_test_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
		     asection *sec,
		     Elf_Internal_Rela *irel,
		     struct misc *misc)
{
  bfd_vma symval;

  /* Get the value of the symbol referred to by the reloc.  */
  symval = symbol_value (abfd, misc->symtab_hdr, misc->isymbuf, irel);
  if (symval == UNDEFINED_SYMBOL)
    /* This appears to be a reference to an undefined
       symbol.  Just ignore it--it will be caught by the
       regular reloc processing.  */
    return FALSE;

  /* Test if we can delete this page instruction.  */
  if (PAGENO (symval + irel->r_addend) !=
      ip2k_nominal_page_bits (abfd, sec, irel->r_offset, misc->contents))
    return FALSE;

  return TRUE;
}

/* Parts of a Stabs entry.  */

#define STRDXOFF   0
#define TYPEOFF    4
#define OTHEROFF   5
#define DESCOFF    6
#define VALOFF     8
#define STABSIZE   12

/* Adjust all the relocations entries after adding or inserting instructions.  */

static void
adjust_all_relocations (bfd *abfd,
			asection *sec,
			bfd_vma addr,
			bfd_vma endaddr,
			int count,
			int noadj)
{
  Elf_Internal_Shdr *symtab_hdr;
  Elf_Internal_Sym *isymbuf, *isym, *isymend;
  unsigned int shndx;
  Elf_Internal_Rela *irel, *irelend, *irelbase;
  struct elf_link_hash_entry **sym_hashes;
  struct elf_link_hash_entry **end_hashes;
  unsigned int symcount;
  asection *stab;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
  isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;

  shndx = _bfd_elf_section_from_bfd_section (abfd, sec);

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

  for (irel = irelbase; irel < irelend; irel++)
    {
      if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
        {
          /* Get the value of the symbol referred to by the reloc.  */
          if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
            {
              asection *sym_sec;

              /* A local symbol.  */
	      isym = isymbuf + ELF32_R_SYM (irel->r_info);
              sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);

              if (isym->st_shndx == shndx)
                {
                  bfd_vma baseaddr = BASEADDR (sec);
                  bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
                                   + irel->r_addend;

                  if ((baseaddr + addr + noadj) <= symval
                      && symval < (baseaddr + endaddr))
                    irel->r_addend += count;
                }
            }
        }

      /* Do this only for PC space relocations.  */
      if (addr <= irel->r_offset && irel->r_offset < endaddr)
        irel->r_offset += count;
    }

  /* Now fix the stab relocations.  */
  stab = bfd_get_section_by_name (abfd, ".stab");
  if (stab)
    {
      bfd_byte *stabcontents, *stabend, *stabp;
      bfd_size_type stab_size = stab->rawsize ? stab->rawsize : stab->size;

      irelbase = elf_section_data (stab)->relocs;
      irelend = irelbase + stab->reloc_count;

      /* Pull out the contents of the stab section.  */
      if (elf_section_data (stab)->this_hdr.contents != NULL)
	stabcontents = elf_section_data (stab)->this_hdr.contents;
      else
	{
	  if (!bfd_malloc_and_get_section (abfd, stab, &stabcontents))
	    {
	      if (stabcontents != NULL)
		free (stabcontents);
	      return;
	    }

	  /* We need to remember this.  */
	  elf_section_data (stab)->this_hdr.contents = stabcontents;
	}

      stabend = stabcontents + stab_size;

      for (irel = irelbase; irel < irelend; irel++)
	{
	  if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
	    {
	      /* Get the value of the symbol referred to by the reloc.  */
	      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
		{
		  asection *sym_sec;

		  /* A local symbol.  */
		  isym = isymbuf + ELF32_R_SYM (irel->r_info);
		  sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);

		  if (sym_sec == sec)
		    {
		      const char *name;
		      unsigned char type;
		      bfd_vma value;
		      bfd_vma baseaddr = BASEADDR (sec);
		      bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
			+ irel->r_addend;

		      if ((baseaddr + addr) <= symval
			  && symval <= (baseaddr + endaddr))
			irel->r_addend += count;

		      /* Go hunt up a function and fix its line info if needed.  */
		      stabp = stabcontents + irel->r_offset - 8;

		      /* Go pullout the stab entry.  */
		      type  = bfd_h_get_8 (abfd, stabp + TYPEOFF);
		      value = bfd_h_get_32 (abfd, stabp + VALOFF);

		      name = bfd_get_stab_name (type);

		      if (strcmp (name, "FUN") == 0)
			{
			  int function_adjusted = 0;

			  if (symval > (baseaddr + addr))
			    /* Not in this function.  */
			    continue;

			  /* Hey we got a function hit.  */
			  stabp += STABSIZE;
			  for (;stabp < stabend; stabp += STABSIZE)
			    {
			      /* Go pullout the stab entry.  */
			      type  = bfd_h_get_8 (abfd, stabp + TYPEOFF);
			      value = bfd_h_get_32 (abfd, stabp + VALOFF);

			      name = bfd_get_stab_name (type);

			      if (strcmp (name, "FUN") == 0)
				{
				  /* Hit another function entry.  */
				  if (function_adjusted)
				    {
				      /* Adjust the value.  */
				      value += count;

				      /* We need to put it back.  */
				      bfd_h_put_32 (abfd, value,stabp + VALOFF);
				    }

				  /* And then bale out.  */
				  break;
				}

			      if (strcmp (name, "SLINE") == 0)
				{
				  /* Got a line entry.  */
				  if ((baseaddr + addr) <= (symval + value))
				    {
				      /* Adjust the line entry.  */
				      value += count;

				      /* We need to put it back.  */
				      bfd_h_put_32 (abfd, value,stabp + VALOFF);
				      function_adjusted = 1;
				    }
				}
			    }
			}
		    }
		}
	    }
	}
    }

  /* When adding an instruction back it is sometimes necessary to move any
     global or local symbol that was referencing the first instruction of
     the moved block to refer to the first instruction of the inserted block.

     For example adding a PAGE instruction before a CALL or JMP requires
     that any label on the CALL or JMP is moved to the PAGE insn.  */
  addr += noadj;

  /* Adjust the local symbols defined in this section.  */
  isymend = isymbuf + symtab_hdr->sh_info;
  for (isym = isymbuf; isym < isymend; isym++)
    {
      if (isym->st_shndx == shndx
	  && addr <= isym->st_value
	  && isym->st_value < endaddr)
	isym->st_value += 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 (addr <= sym_hash->root.u.def.value
              && sym_hash->root.u.def.value < endaddr)
	    sym_hash->root.u.def.value += count;
	}
    }

  return;
}

/* Delete some bytes from a section while relaxing.  */

static bfd_boolean
ip2k_elf_relax_delete_bytes (bfd *abfd,
			     asection *sec,
			     bfd_vma addr,
			     int count)
{
  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
  bfd_vma endaddr = sec->size;

  /* Actually delete the bytes.  */
  memmove (contents + addr, contents + addr + count,
	   endaddr - addr - count);

  sec->size -= count;

  adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0);
  return TRUE;
}

static bfd_boolean
ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
		       asection *sec,
		       Elf_Internal_Rela *irel,
		       bfd_boolean *again,
		       struct misc *misc)
{
  /* Note that we've changed the relocs, section contents, etc.  */
  elf_section_data (sec)->relocs = misc->irelbase;
  elf_section_data (sec)->this_hdr.contents = misc->contents;
  misc->symtab_hdr->contents = (bfd_byte *) misc->isymbuf;

  /* Fix the relocation's type.  */
  irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_IP2K_NONE);

  /* Delete the PAGE insn.  */
  if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
    return FALSE;

  /* Modified => will need to iterate relaxation again.  */
  *again = TRUE;

  return TRUE;
}

static bfd_boolean
ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
			     asection *sec,
			     Elf_Internal_Rela *irel,
			     bfd_boolean *again,
			     struct misc *misc)
{
  Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
  Elf_Internal_Rela *ireltest = irel;
  bfd_byte code[4];
  bfd_vma addr;

  /* Test all page instructions.  */
  addr = irel->r_offset;
  while (1)
    {
      if (addr + 4 > sec->size)
	break;

      ip2k_get_mem (abfd, misc->contents + addr, 4, code);
      if ((! IS_PAGE_OPCODE (code + 0))
	  || (! IS_JMP_OPCODE (code + 2)))
	break;

      /* Validate relocation entry (every entry should have a matching
          relocation entry).  */
      if (ireltest >= irelend)
        {
	  _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
          return FALSE;
        }

      if (ireltest->r_offset != addr)
        {
	  _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
          return FALSE;
        }

      if (! ip2k_test_page_insn (abfd, sec, ireltest, misc))
	/* Un-removable page insn => nothing can be done.  */
	return TRUE;

      addr += 4;
      ireltest += 2;
    }

  /* Relaxable. Adjust table header.  */
  ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 4, code);
  if ((! IS_ADD_W_WREG_OPCODE (code + 0))
      || (! IS_ADD_PCL_W_OPCODE (code + 2)))
    {
      _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
      return FALSE;
    }

  if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset - 4, 2))
    return FALSE;

  *again = TRUE;

  /* Delete all page instructions in table.  */
  while (irel < ireltest)
    {
      if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
	return FALSE;
      irel += 2;
    }

  return TRUE;
}

static bfd_boolean
ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
			     asection *sec,
			     Elf_Internal_Rela *irel,
			     bfd_boolean *again,
			     struct misc *misc)
{
  Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
  Elf_Internal_Rela *ireltest = irel;
  bfd_byte code[12];
  bfd_vma addr;

  /* Test all page instructions.  */
  addr = irel->r_offset;

  while (1)
    {
      if (addr + 4 > sec->size)
	break;

      ip2k_get_mem (abfd, misc->contents + addr, 4, code);

      if ((! IS_PAGE_OPCODE (code + 0))
	  || (! IS_JMP_OPCODE (code + 2)))
	break;

      /* Validate relocation entry (every entry should have a matching
          relocation entry).  */
      if (ireltest >= irelend)
        {
          _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
          return FALSE;
        }

      if (ireltest->r_offset != addr)
        {
          _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
          return FALSE;
        }

      if (!ip2k_test_page_insn (abfd, sec, ireltest, misc))
	/* Un-removable page insn => nothing can be done.  */
	return TRUE;

      addr += 4;
      ireltest += 2;
    }

  /* Relaxable. Adjust table header.  */
  ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 2, code);
  if (IS_PAGE_OPCODE (code))
    addr = irel->r_offset - 16;
  else
    addr = irel->r_offset - 14;

  ip2k_get_mem (abfd, misc->contents + addr, 12, code);
  if ((!IS_ADD_W_WREG_OPCODE (code + 0))
      || (!IS_SNC_OPCODE (code + 2))
      || (!IS_INC_1SP_OPCODE (code + 4))
      || (!IS_ADD_2SP_W_OPCODE (code + 6))
      || (!IS_SNC_OPCODE (code + 8))
      || (!IS_INC_1SP_OPCODE (code + 10)))
    {
      _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
      return FALSE;
    }

  /* Delete first 3 opcodes.  */
  if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6))
    return FALSE;

  *again = TRUE;

  /* Delete all page instructions in table.  */
  while (irel < ireltest)
    {
      if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
	return FALSE;
      irel += 2;
    }

  return TRUE;
}

/* This function handles relaxation of a section in a specific page.  */

static bfd_boolean
ip2k_elf_relax_section_page (bfd *abfd,
			     asection *sec,
			     bfd_boolean *again,
			     struct misc *misc,
			     unsigned long page_start,
			     unsigned long page_end)
{
  Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
  Elf_Internal_Rela *irel;
  int switch_table_128;
  int switch_table_256;

  /* Walk thru the section looking for relaxation opportunities.  */
  for (irel = misc->irelbase; irel < irelend; irel++)
    {
      if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3)
	/* Ignore non page instructions.  */
	continue;

      if (BASEADDR (sec) + irel->r_offset < page_start)
	/* Ignore page instructions on earlier page - they have
	   already been processed. Remember that there is code flow
	   that crosses a page boundary.  */
	continue;

      if (BASEADDR (sec) + irel->r_offset > page_end)
	/* Flow beyond end of page => nothing more to do for this page.  */
	return TRUE;

      /* Detect switch tables.  */
      switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents);
      switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents);

      if ((switch_table_128 > 0) || (switch_table_256 > 0))
	/* If the index is greater than 0 then it has already been processed.  */
	continue;

      if (switch_table_128 == 0)
	{
	  if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc))
	    return FALSE;

	  continue;
	}

      if (switch_table_256 == 0)
	{
	  if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc))
	    return FALSE;

	  continue;
	}

      /* Simple relax.  */
      if (ip2k_test_page_insn (abfd, sec, irel, misc))
	{
	  if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
	    return FALSE;

	  continue;
	}
    }

  return TRUE;
}

/* This function handles relaxing for the ip2k.

   Principle: Start with the first page and remove page instructions that
   are not require on this first page. By removing page instructions more
   code will fit into this page - repeat until nothing more can be achieved
   for this page. Move on to the next page.

   Processing the pages one at a time from the lowest page allows a removal
   only policy to be used - pages can be removed but are never reinserted.  */

static bfd_boolean
ip2k_elf_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;
  bfd_byte *contents = NULL;
  Elf_Internal_Sym *isymbuf = NULL;
  static asection * first_section = NULL;
  static unsigned long search_addr;
  static unsigned long page_start = 0;
  static unsigned long page_end = 0;
  static unsigned int pass = 0;
  static bfd_boolean new_pass = FALSE;
  static bfd_boolean changed = FALSE;
  struct misc misc;

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

  if (first_section == NULL)
    {
      ip2k_relaxed = TRUE;
      first_section = sec;
    }

  if (first_section == sec)
    {
      pass++;
      new_pass = TRUE;
    }

  /* 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 (link_info->relocatable
      || (sec->flags & SEC_RELOC) == 0
      || sec->reloc_count == 0
      || (sec->flags & SEC_CODE) == 0)
    return TRUE;

  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;

  internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
					       link_info->keep_memory);
  if (internal_relocs == NULL)
    goto error_return;

  /* Get section contents cached copy if it exists.  */
  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
	{
	  /* Go get them off disk.  */
	  if (!bfd_malloc_and_get_section (abfd, sec, &contents))
	    goto error_return;
	}
    }

  /* Read this BFD's symbols cached copy if it exists.  */
  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;
    }

  misc.symtab_hdr = symtab_hdr;
  misc.isymbuf = isymbuf;
  misc.irelbase = internal_relocs;
  misc.contents = contents;

  /* This is where all the relaxation actually get done.  */
  if ((pass == 1) || (new_pass && !changed))
    {
      /* On the first pass we simply search for the lowest page that
         we havn't relaxed yet. Note that the pass count is reset
         each time a page is complete in order to move on to the next page.
         If we can't find any more pages then we are finished.  */
      if (new_pass)
	{
	  pass = 1;
	  new_pass = FALSE;
	  changed = TRUE; /* Pre-initialize to break out of pass 1.  */
	  search_addr = 0xFFFFFFFF;
	}

      if ((BASEADDR (sec) + sec->size < search_addr)
	  && (BASEADDR (sec) + sec->size > page_end))
	{
	  if (BASEADDR (sec) <= page_end)
	    search_addr = page_end + 1;
	  else
	    search_addr = BASEADDR (sec);

	  /* Found a page => more work to do.  */
	  *again = TRUE;
	}
    }
  else
    {
      if (new_pass)
	{
	  new_pass = FALSE;
	  changed = FALSE;
	  page_start = PAGENO (search_addr);
	  page_end = page_start | 0x00003FFF;
	}

      /* Only process sections in range.  */
      if ((BASEADDR (sec) + sec->size >= page_start)
	  && (BASEADDR (sec) <= page_end))
	{
          if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end))
	    return FALSE;
	}
      *again = TRUE;
    }

  /* Perform some house keeping after relaxing the section.  */

  if (isymbuf != NULL
      && symtab_hdr->contents != (unsigned char *) isymbuf)
    {
      if (! link_info->keep_memory)
	free (isymbuf);
      else
	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 (internal_relocs != NULL
      && elf_section_data (sec)->relocs != internal_relocs)
    free (internal_relocs);

  return TRUE;

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

/* Set the howto pointer for a IP2K ELF reloc.  */

static void
ip2k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
			 arelent * cache_ptr,
			 Elf_Internal_Rela * dst)
{
  unsigned int r_type;

  r_type = ELF32_R_TYPE (dst->r_info);
  if (r_type >= (unsigned int) R_IP2K_max)
    {
      _bfd_error_handler (_("%B: invalid IP2K reloc number: %d"), abfd, r_type);
      r_type = 0;
    }
  cache_ptr->howto = & ip2k_elf_howto_table [r_type];
}

/* Perform a single relocation.
   By default we use the standard BFD routines.  */

static bfd_reloc_status_type
ip2k_final_link_relocate (reloc_howto_type *  howto,
			  bfd *               input_bfd,
			  asection *          input_section,
			  bfd_byte *          contents,
			  Elf_Internal_Rela * rel,
			  bfd_vma             relocation)
{
  static bfd_vma page_addr = 0;

  bfd_reloc_status_type r = bfd_reloc_ok;
  switch (howto->type)
    {
      /* Handle data space relocations.  */
    case R_IP2K_FR9:
    case R_IP2K_BANK:
      if ((relocation & IP2K_DATA_MASK) == IP2K_DATA_VALUE)
	relocation &= ~IP2K_DATA_MASK;
      else
	r = bfd_reloc_notsupported;
      break;

    case R_IP2K_LO8DATA:
    case R_IP2K_HI8DATA:
    case R_IP2K_EX8DATA:
      break;

      /* Handle insn space relocations.  */
    case R_IP2K_PAGE3:
      page_addr = BASEADDR (input_section) + rel->r_offset;
      if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
	relocation &= ~IP2K_INSN_MASK;
      else
	r = bfd_reloc_notsupported;
      break;

    case R_IP2K_ADDR16CJP:
      if (BASEADDR (input_section) + rel->r_offset != page_addr + 2)
	{
	  /* No preceding page instruction, verify that it isn't needed.  */
	  if (PAGENO (relocation + rel->r_addend) !=
	      ip2k_nominal_page_bits (input_bfd, input_section,
	      			      rel->r_offset, contents))
	    _bfd_error_handler (_("ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."),
				BASEADDR (input_section) + rel->r_offset,
				relocation + rel->r_addend);
        }
      else if (ip2k_relaxed)
        {
          /* Preceding page instruction. Verify that the page instruction is
             really needed. One reason for the relaxation to miss a page is if
             the section is not marked as executable.  */
	  if (!ip2k_is_switch_table_128 (input_bfd, input_section,
					 rel->r_offset - 2, contents)
	      && !ip2k_is_switch_table_256 (input_bfd, input_section,
					    rel->r_offset - 2, contents)
	      && (PAGENO (relocation + rel->r_addend) ==
		  ip2k_nominal_page_bits (input_bfd, input_section,
					  rel->r_offset - 2, contents)))
	    _bfd_error_handler (_("ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."),
				page_addr,
				relocation + rel->r_addend);
        }
      if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
	relocation &= ~IP2K_INSN_MASK;
      else
	r = bfd_reloc_notsupported;
      break;

    case R_IP2K_LO8INSN:
    case R_IP2K_HI8INSN:
    case R_IP2K_PC_SKIP:
      if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
	relocation &= ~IP2K_INSN_MASK;
      else
	r = bfd_reloc_notsupported;
      break;

    case R_IP2K_16:
      /* If this is a relocation involving a TEXT
	 symbol, reduce it to a word address.  */
      if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
	howto = &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
      break;

      /* Pass others through.  */
    default:
      break;
    }

  /* Only install relocation if above tests did not disqualify it.  */
  if (r == bfd_reloc_ok)
    r = _bfd_final_link_relocate (howto, input_bfd, input_section,
				  contents, rel->r_offset,
				  relocation, rel->r_addend);

  return r;
}

/* Relocate a IP2K ELF section.

   The RELOCATE_SECTION function is called by the new ELF backend linker
   to handle the relocations for a section.

   The relocs are always passed as Rela structures; if the section
   actually uses Rel structures, the r_addend field will always be
   zero.

   This function is responsible for adjusting the section contents as
   necessary, and (if using Rela relocs and generating a relocatable
   output file) adjusting the reloc addend as necessary.

   This function does not have to worry about setting the reloc
   address or the reloc symbol index.

   LOCAL_SYMS is a pointer to the swapped in local symbols.

   LOCAL_SECTIONS is an array giving the section in the input file
   corresponding to the st_shndx field of each local symbol.

   The global hash table entry for the global symbols can be found
   via elf_sym_hashes (input_bfd).

   When generating relocatable output, this function must handle
   STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
   going to be the section symbol corresponding to the output
   section, which means that the addend must be adjusted
   accordingly.  */

static bfd_boolean
ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
			   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;
  struct elf_link_hash_entry **sym_hashes;
  Elf_Internal_Rela *rel;
  Elf_Internal_Rela *relend;

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

  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;
      const char *                 name = NULL;
      int                          r_type;

      r_type = ELF32_R_TYPE (rel->r_info);
      r_symndx = ELF32_R_SYM (rel->r_info);
      howto  = ip2k_elf_howto_table + r_type;
      h      = NULL;
      sym    = NULL;
      sec    = NULL;

      if (r_symndx < symtab_hdr->sh_info)
	{
	  sym = local_syms + r_symndx;
	  sec = local_sections [r_symndx];
	  relocation = BASEADDR (sec) + sym->st_value;

	  name = bfd_elf_string_from_elf_section
	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
	}
      else
	{
	  bfd_boolean warned, ignored;
	  bfd_boolean unresolved_reloc;

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

	  name = h->root.root.string;
	}

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

      if (info->relocatable)
	continue;

      /* Finally, the sole IP2K-specific part.  */
      r = ip2k_final_link_relocate (howto, input_bfd, input_section,
				     contents, rel, relocation);

      if (r != bfd_reloc_ok)
	{
	  const char * msg = NULL;

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

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

	    case bfd_reloc_outofrange:
	      msg = _("internal error: out of range error");
	      break;

	      /* This is how ip2k_final_link_relocate tells us of a non-kosher
                 reference between insn & data address spaces.  */
	    case bfd_reloc_notsupported:
              if (sym != NULL) /* Only if it's not an unresolved symbol.  */
	         msg = _("unsupported relocation between data/insn address spaces");
	      break;

	    case bfd_reloc_dangerous:
	      msg = _("internal error: dangerous relocation");
	      break;

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

	  if (msg)
	    r = info->callbacks->warning
	      (info, msg, name, input_bfd, input_section, rel->r_offset);

	  if (! r)
	    return FALSE;
	}
    }

  return TRUE;
}

#define TARGET_BIG_SYM	 ip2k_elf32_vec
#define TARGET_BIG_NAME  "elf32-ip2k"

#define ELF_ARCH	 bfd_arch_ip2k
#define ELF_MACHINE_CODE EM_IP2K
#define ELF_MACHINE_ALT1 EM_IP2K_OLD
#define ELF_MAXPAGESIZE  1 /* No pages on the IP2K.  */

#define elf_info_to_howto_rel			NULL
#define elf_info_to_howto			ip2k_info_to_howto_rela

#define elf_backend_can_gc_sections     	1
#define elf_backend_rela_normal			1
#define elf_backend_relocate_section		ip2k_elf_relocate_section

#define elf_symbol_leading_char			'_'
#define bfd_elf32_bfd_reloc_type_lookup		ip2k_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup	ip2k_reloc_name_lookup
#define bfd_elf32_bfd_relax_section		ip2k_elf_relax_section

#include "elf32-target.h"
