/* Ubicom IP2xxx specific support for 32-bit ELF
   Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, 2010, 2012
   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,2,32, 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);
  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;
	  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);

	  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	 bfd_elf32_ip2k_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"
