Home | History | Annotate | Line # | Download | only in bfd
elf32-ip2k.c revision 1.11
      1   1.1  christos /* Ubicom IP2xxx specific support for 32-bit ELF
      2  1.11  christos    Copyright (C) 2000-2024 Free Software Foundation, Inc.
      3   1.1  christos 
      4   1.1  christos    This file is part of BFD, the Binary File Descriptor library.
      5   1.1  christos 
      6   1.1  christos    This program is free software; you can redistribute it and/or modify
      7   1.1  christos    it under the terms of the GNU General Public License as published by
      8   1.1  christos    the Free Software Foundation; either version 3 of the License, or
      9   1.1  christos    (at your option) any later version.
     10   1.1  christos 
     11   1.1  christos    This program is distributed in the hope that it will be useful,
     12   1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13   1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14   1.1  christos    GNU General Public License for more details.
     15   1.1  christos 
     16   1.1  christos    You should have received a copy of the GNU General Public License
     17   1.1  christos    along with this program; if not, write to the Free Software
     18   1.1  christos    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19   1.1  christos    MA 02110-1301, USA.  */
     20   1.1  christos 
     21   1.1  christos #include "sysdep.h"
     22   1.1  christos #include "bfd.h"
     23   1.1  christos #include "libbfd.h"
     24   1.1  christos #include "elf-bfd.h"
     25   1.1  christos #include "elf/ip2k.h"
     26   1.1  christos 
     27   1.1  christos /* Struct used to pass miscellaneous paramaters which
     28   1.1  christos    helps to avoid overly long parameter lists.  */
     29   1.1  christos struct misc
     30   1.1  christos {
     31   1.1  christos   Elf_Internal_Shdr *  symtab_hdr;
     32   1.1  christos   Elf_Internal_Rela *  irelbase;
     33   1.8  christos   bfd_byte *	       contents;
     34   1.1  christos   Elf_Internal_Sym *   isymbuf;
     35   1.1  christos };
     36   1.1  christos 
     37   1.1  christos struct ip2k_opcode
     38   1.1  christos {
     39   1.1  christos   unsigned short opcode;
     40   1.1  christos   unsigned short mask;
     41   1.1  christos };
     42   1.1  christos 
     43  1.10  christos static bool ip2k_relaxed = false;
     44   1.1  christos 
     45   1.1  christos static const struct ip2k_opcode ip2k_page_opcode[] =
     46   1.1  christos {
     47   1.1  christos   {0x0010, 0xFFF8},	/* Page.  */
     48   1.1  christos   {0x0000, 0x0000},
     49   1.1  christos };
     50   1.1  christos 
     51   1.1  christos #define IS_PAGE_OPCODE(code) \
     52   1.1  christos   ip2k_is_opcode (code, ip2k_page_opcode)
     53   1.1  christos 
     54   1.1  christos static const struct ip2k_opcode ip2k_jmp_opcode[] =
     55   1.1  christos {
     56   1.1  christos   {0xE000, 0xE000},	/* Jmp.  */
     57   1.1  christos   {0x0000, 0x0000},
     58   1.1  christos };
     59   1.1  christos 
     60   1.1  christos #define IS_JMP_OPCODE(code) \
     61   1.1  christos   ip2k_is_opcode (code, ip2k_jmp_opcode)
     62   1.1  christos 
     63   1.1  christos static const struct ip2k_opcode ip2k_snc_opcode[] =
     64   1.1  christos {
     65   1.1  christos   {0xA00B, 0xFFFF},	/* Snc.  */
     66   1.1  christos   {0x0000, 0x0000},
     67   1.1  christos };
     68   1.1  christos 
     69   1.1  christos #define IS_SNC_OPCODE(code) \
     70   1.1  christos   ip2k_is_opcode (code, ip2k_snc_opcode)
     71   1.1  christos 
     72   1.1  christos static const struct ip2k_opcode ip2k_inc_1sp_opcode[] =
     73   1.1  christos {
     74   1.1  christos   {0x2B81, 0xFFFF},	/* Inc 1(SP).  */
     75   1.1  christos   {0x0000, 0x0000},
     76   1.1  christos };
     77   1.1  christos 
     78   1.1  christos #define IS_INC_1SP_OPCODE(code) \
     79   1.1  christos   ip2k_is_opcode (code, ip2k_inc_1sp_opcode)
     80   1.1  christos 
     81   1.1  christos static const struct ip2k_opcode ip2k_add_2sp_w_opcode[] =
     82   1.1  christos {
     83   1.1  christos   {0x1F82, 0xFFFF},	/* Add 2(SP),w.  */
     84   1.1  christos   {0x0000, 0x0000},
     85   1.1  christos };
     86   1.1  christos 
     87   1.1  christos #define IS_ADD_2SP_W_OPCODE(code) \
     88   1.1  christos   ip2k_is_opcode (code, ip2k_add_2sp_w_opcode)
     89   1.1  christos 
     90   1.1  christos static const struct ip2k_opcode ip2k_add_w_wreg_opcode[] =
     91   1.1  christos {
     92   1.1  christos   {0x1C0A, 0xFFFF},	/* Add w,wreg.  */
     93   1.1  christos   {0x1E0A, 0xFFFF},	/* Add wreg,w.  */
     94   1.1  christos   {0x0000, 0x0000},
     95   1.1  christos };
     96   1.1  christos 
     97   1.1  christos #define IS_ADD_W_WREG_OPCODE(code) \
     98   1.1  christos   ip2k_is_opcode (code, ip2k_add_w_wreg_opcode)
     99   1.1  christos 
    100   1.1  christos static const struct ip2k_opcode ip2k_add_pcl_w_opcode[] =
    101   1.1  christos {
    102   1.1  christos   {0x1E09, 0xFFFF},	/* Add pcl,w.  */
    103   1.1  christos   {0x0000, 0x0000},
    104   1.1  christos };
    105   1.1  christos 
    106   1.1  christos #define IS_ADD_PCL_W_OPCODE(code) \
    107   1.1  christos   ip2k_is_opcode (code, ip2k_add_pcl_w_opcode)
    108   1.1  christos 
    109   1.1  christos static const struct ip2k_opcode ip2k_skip_opcodes[] =
    110   1.1  christos {
    111   1.1  christos   {0xB000, 0xF000},	/* sb */
    112   1.1  christos   {0xA000, 0xF000},	/* snb */
    113   1.1  christos   {0x7600, 0xFE00},	/* cse/csne #lit */
    114   1.1  christos   {0x5800, 0xFC00},	/* incsnz */
    115   1.1  christos   {0x4C00, 0xFC00},	/* decsnz */
    116   1.1  christos   {0x4000, 0xFC00},	/* cse/csne */
    117   1.1  christos   {0x3C00, 0xFC00},	/* incsz */
    118   1.1  christos   {0x2C00, 0xFC00},	/* decsz */
    119   1.1  christos   {0x0000, 0x0000},
    120   1.1  christos };
    121   1.1  christos 
    122   1.1  christos #define IS_SKIP_OPCODE(code) \
    123   1.1  christos   ip2k_is_opcode (code, ip2k_skip_opcodes)
    124   1.1  christos 
    125   1.1  christos /* Relocation tables.  */
    126   1.1  christos static reloc_howto_type ip2k_elf_howto_table [] =
    127   1.1  christos {
    128   1.1  christos #define IP2K_HOWTO(t,rs,s,bs,pr,bp,name,sm,dm) \
    129   1.8  christos     HOWTO(t,			/* type */ \
    130   1.8  christos 	  rs,			/* rightshift */ \
    131   1.8  christos 	  s,			/* size (0 = byte, 1 = short, 2 = long) */ \
    132   1.8  christos 	  bs,			/* bitsize */ \
    133   1.8  christos 	  pr,			/* pc_relative */ \
    134   1.8  christos 	  bp,			/* bitpos */ \
    135   1.8  christos 	  complain_overflow_dont,/* complain_on_overflow */ \
    136   1.8  christos 	  bfd_elf_generic_reloc,/* special_function */ \
    137   1.8  christos 	  name,			/* name */ \
    138  1.10  christos 	  false,		/* partial_inplace */ \
    139   1.8  christos 	  sm,			/* src_mask */ \
    140   1.8  christos 	  dm,			/* dst_mask */ \
    141   1.8  christos 	  pr)			/* pcrel_offset */
    142   1.1  christos 
    143   1.1  christos   /* This reloc does nothing.  */
    144  1.10  christos   IP2K_HOWTO (R_IP2K_NONE, 0,0,0, false, 0, "R_IP2K_NONE", 0, 0),
    145   1.1  christos   /* A 16 bit absolute relocation.  */
    146  1.10  christos   IP2K_HOWTO (R_IP2K_16, 0,2,16, false, 0, "R_IP2K_16", 0, 0xffff),
    147   1.1  christos   /* A 32 bit absolute relocation.  */
    148  1.10  christos   IP2K_HOWTO (R_IP2K_32, 0,4,32, false, 0, "R_IP2K_32", 0, 0xffffffff),
    149   1.1  christos   /* A 8-bit data relocation for the FR9 field.  Ninth bit is computed specially.  */
    150  1.10  christos   IP2K_HOWTO (R_IP2K_FR9, 0,2,9, false, 0, "R_IP2K_FR9", 0, 0x00ff),
    151   1.1  christos   /* A 4-bit data relocation.  */
    152  1.10  christos   IP2K_HOWTO (R_IP2K_BANK, 8,2,4, false, 0, "R_IP2K_BANK", 0, 0x000f),
    153   1.1  christos   /* A 13-bit insn relocation - word address => right-shift 1 bit extra.  */
    154  1.10  christos   IP2K_HOWTO (R_IP2K_ADDR16CJP, 1,2,13, false, 0, "R_IP2K_ADDR16CJP", 0, 0x1fff),
    155   1.1  christos   /* A 3-bit insn relocation - word address => right-shift 1 bit extra.  */
    156  1.10  christos   IP2K_HOWTO (R_IP2K_PAGE3, 14,2,3, false, 0, "R_IP2K_PAGE3", 0, 0x0007),
    157   1.1  christos   /* Two 8-bit data relocations.  */
    158  1.10  christos   IP2K_HOWTO (R_IP2K_LO8DATA, 0,2,8, false, 0, "R_IP2K_LO8DATA", 0, 0x00ff),
    159  1.10  christos   IP2K_HOWTO (R_IP2K_HI8DATA, 8,2,8, false, 0, "R_IP2K_HI8DATA", 0, 0x00ff),
    160   1.1  christos   /* Two 8-bit insn relocations.  word address => right-shift 1 bit extra.  */
    161  1.10  christos   IP2K_HOWTO (R_IP2K_LO8INSN, 1,2,8, false, 0, "R_IP2K_LO8INSN", 0, 0x00ff),
    162  1.10  christos   IP2K_HOWTO (R_IP2K_HI8INSN, 9,2,8, false, 0, "R_IP2K_HI8INSN", 0, 0x00ff),
    163   1.1  christos 
    164   1.1  christos   /* Special 1 bit relocation for SKIP instructions.  */
    165  1.10  christos   IP2K_HOWTO (R_IP2K_PC_SKIP, 1,2,1, false, 12, "R_IP2K_PC_SKIP", 0xfffe, 0x1000),
    166   1.1  christos   /* 16 bit word address.  */
    167  1.10  christos   IP2K_HOWTO (R_IP2K_TEXT, 1,2,16, false, 0, "R_IP2K_TEXT", 0, 0xffff),
    168   1.1  christos   /* A 7-bit offset relocation for the FR9 field.  Eigth and ninth bit comes from insn.  */
    169  1.10  christos   IP2K_HOWTO (R_IP2K_FR_OFFSET, 0,2,9, false, 0, "R_IP2K_FR_OFFSET", 0x180, 0x007f),
    170   1.1  christos   /* Bits 23:16 of an address.  */
    171  1.10  christos   IP2K_HOWTO (R_IP2K_EX8DATA, 16,2,8, false, 0, "R_IP2K_EX8DATA", 0, 0x00ff),
    172   1.1  christos };
    173   1.1  christos 
    174   1.1  christos 
    175   1.1  christos /* Map BFD reloc types to IP2K ELF reloc types.  */
    176   1.1  christos 
    177   1.1  christos static reloc_howto_type *
    178   1.1  christos ip2k_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
    179   1.1  christos 			bfd_reloc_code_real_type code)
    180   1.1  christos {
    181   1.1  christos   /* Note that the ip2k_elf_howto_table is indxed by the R_
    182   1.1  christos      constants.  Thus, the order that the howto records appear in the
    183   1.1  christos      table *must* match the order of the relocation types defined in
    184   1.1  christos      include/elf/ip2k.h.  */
    185   1.1  christos 
    186   1.1  christos   switch (code)
    187   1.1  christos     {
    188   1.1  christos     case BFD_RELOC_NONE:
    189   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_NONE];
    190   1.1  christos     case BFD_RELOC_16:
    191   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_16];
    192   1.1  christos     case BFD_RELOC_32:
    193   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_32];
    194   1.1  christos     case BFD_RELOC_IP2K_FR9:
    195   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_FR9];
    196   1.1  christos     case BFD_RELOC_IP2K_BANK:
    197   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_BANK];
    198   1.1  christos     case BFD_RELOC_IP2K_ADDR16CJP:
    199   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_ADDR16CJP];
    200   1.1  christos     case BFD_RELOC_IP2K_PAGE3:
    201   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_PAGE3];
    202   1.1  christos     case BFD_RELOC_IP2K_LO8DATA:
    203   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_LO8DATA];
    204   1.1  christos     case BFD_RELOC_IP2K_HI8DATA:
    205   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_HI8DATA];
    206   1.1  christos     case BFD_RELOC_IP2K_LO8INSN:
    207   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_LO8INSN];
    208   1.1  christos     case BFD_RELOC_IP2K_HI8INSN:
    209   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_HI8INSN];
    210   1.1  christos     case BFD_RELOC_IP2K_PC_SKIP:
    211   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_PC_SKIP];
    212   1.1  christos     case BFD_RELOC_IP2K_TEXT:
    213   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
    214   1.1  christos     case BFD_RELOC_IP2K_FR_OFFSET:
    215   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_FR_OFFSET];
    216   1.1  christos     case BFD_RELOC_IP2K_EX8DATA:
    217   1.1  christos       return &ip2k_elf_howto_table[ (int) R_IP2K_EX8DATA];
    218   1.1  christos     default:
    219   1.1  christos       /* Pacify gcc -Wall.  */
    220   1.1  christos       return NULL;
    221   1.1  christos     }
    222   1.1  christos   return NULL;
    223   1.1  christos }
    224   1.1  christos 
    225   1.1  christos static reloc_howto_type *
    226   1.1  christos ip2k_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
    227   1.1  christos {
    228   1.1  christos   unsigned int i;
    229   1.1  christos 
    230   1.1  christos   for (i = 0;
    231   1.1  christos        i < sizeof (ip2k_elf_howto_table) / sizeof (ip2k_elf_howto_table[0]);
    232   1.1  christos        i++)
    233   1.1  christos     if (ip2k_elf_howto_table[i].name != NULL
    234   1.1  christos 	&& strcasecmp (ip2k_elf_howto_table[i].name, r_name) == 0)
    235   1.1  christos       return &ip2k_elf_howto_table[i];
    236   1.1  christos 
    237   1.1  christos   return NULL;
    238   1.1  christos }
    239   1.1  christos 
    240   1.1  christos static void
    241   1.1  christos ip2k_get_mem (bfd *abfd ATTRIBUTE_UNUSED,
    242   1.1  christos 	      bfd_byte *addr,
    243   1.1  christos 	      int length,
    244   1.1  christos 	      bfd_byte *ptr)
    245   1.1  christos {
    246   1.1  christos   while (length --)
    247   1.1  christos     * ptr ++ = bfd_get_8 (abfd, addr ++);
    248   1.1  christos }
    249   1.1  christos 
    250  1.10  christos static bool
    251   1.1  christos ip2k_is_opcode (bfd_byte *code, const struct ip2k_opcode *opcodes)
    252   1.1  christos {
    253   1.1  christos   unsigned short insn = (code[0] << 8) | code[1];
    254   1.1  christos 
    255   1.1  christos   while (opcodes->mask != 0)
    256   1.1  christos     {
    257   1.1  christos       if ((insn & opcodes->mask) == opcodes->opcode)
    258  1.10  christos 	return true;
    259   1.1  christos 
    260   1.1  christos       opcodes ++;
    261   1.1  christos     }
    262   1.1  christos 
    263  1.10  christos   return false;
    264   1.1  christos }
    265   1.1  christos 
    266   1.1  christos #define PAGENO(ABSADDR) ((ABSADDR) & 0xFFFFC000)
    267   1.1  christos #define BASEADDR(SEC)	((SEC)->output_section->vma + (SEC)->output_offset)
    268   1.1  christos 
    269   1.1  christos #define UNDEFINED_SYMBOL (~(bfd_vma)0)
    270   1.1  christos 
    271   1.1  christos /* Return the value of the symbol associated with the relocation IREL.  */
    272   1.1  christos 
    273   1.1  christos static bfd_vma
    274   1.1  christos symbol_value (bfd *abfd,
    275   1.1  christos 	      Elf_Internal_Shdr *symtab_hdr,
    276   1.1  christos 	      Elf_Internal_Sym *isymbuf,
    277   1.1  christos 	      Elf_Internal_Rela *irel)
    278   1.1  christos {
    279   1.1  christos   if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    280   1.1  christos     {
    281   1.1  christos       Elf_Internal_Sym *isym;
    282   1.1  christos       asection *sym_sec;
    283   1.1  christos 
    284   1.1  christos       isym = isymbuf + ELF32_R_SYM (irel->r_info);
    285   1.1  christos       if (isym->st_shndx == SHN_UNDEF)
    286   1.1  christos 	sym_sec = bfd_und_section_ptr;
    287   1.1  christos       else if (isym->st_shndx == SHN_ABS)
    288   1.1  christos 	sym_sec = bfd_abs_section_ptr;
    289   1.1  christos       else if (isym->st_shndx == SHN_COMMON)
    290   1.1  christos 	sym_sec = bfd_com_section_ptr;
    291   1.1  christos       else
    292   1.1  christos 	sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
    293   1.1  christos 
    294   1.1  christos       return isym->st_value + BASEADDR (sym_sec);
    295   1.1  christos     }
    296   1.1  christos   else
    297   1.1  christos     {
    298   1.1  christos       unsigned long indx;
    299   1.1  christos       struct elf_link_hash_entry *h;
    300   1.1  christos 
    301   1.1  christos       indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
    302   1.1  christos       h = elf_sym_hashes (abfd)[indx];
    303   1.1  christos       BFD_ASSERT (h != NULL);
    304   1.1  christos 
    305   1.1  christos       if (h->root.type != bfd_link_hash_defined
    306   1.1  christos 	  && h->root.type != bfd_link_hash_defweak)
    307   1.1  christos 	return UNDEFINED_SYMBOL;
    308   1.1  christos 
    309   1.1  christos       return (h->root.u.def.value + BASEADDR (h->root.u.def.section));
    310   1.1  christos     }
    311   1.1  christos }
    312   1.1  christos 
    313   1.1  christos /* Determine if the instruction sequence matches that for
    314   1.1  christos    the prologue of a switch dispatch table with fewer than
    315   1.1  christos    128 entries.
    316   1.1  christos 
    317   1.8  christos 	  sc
    318   1.8  christos 	  page	  $nnn0
    319   1.8  christos 	  jmp	  $nnn0
    320   1.8  christos 	  add	  w,wreg
    321   1.8  christos 	  add	  pcl,w
    322   1.1  christos   addr=>
    323   1.8  christos 	  page	  $nnn1
    324   1.8  christos 	  jmp	  $nnn1
    325   1.8  christos 	   page	   $nnn2
    326   1.8  christos 	   jmp	   $nnn2
    327   1.8  christos 	   ...
    328   1.8  christos 	   page	   $nnnN
    329   1.8  christos 	   jmp	   $nnnN
    330   1.1  christos 
    331   1.1  christos   After relaxation.
    332   1.8  christos 	   sc
    333   1.8  christos 	   page	   $nnn0
    334   1.8  christos 	   jmp	   $nnn0
    335   1.8  christos 	   add	   pcl,w
    336   1.1  christos   addr=>
    337   1.8  christos 	   jmp	   $nnn1
    338   1.8  christos 	   jmp	   $nnn2
    339   1.8  christos 	   ...
    340   1.8  christos 	  jmp	  $nnnN  */
    341   1.1  christos 
    342   1.1  christos static int
    343   1.1  christos ip2k_is_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
    344   1.1  christos 			  asection *sec,
    345   1.1  christos 			  bfd_vma addr,
    346   1.1  christos 			  bfd_byte *contents)
    347   1.1  christos {
    348   1.1  christos   bfd_byte code[4];
    349   1.1  christos   int table_index = 0;
    350   1.1  christos 
    351   1.1  christos   /* Check current page-jmp.  */
    352   1.1  christos   if (addr + 4 > sec->size)
    353   1.1  christos     return -1;
    354   1.1  christos 
    355   1.1  christos   ip2k_get_mem (abfd, contents + addr, 4, code);
    356   1.1  christos 
    357   1.1  christos   if ((! IS_PAGE_OPCODE (code + 0))
    358   1.1  christos       || (! IS_JMP_OPCODE (code + 2)))
    359   1.1  christos     return -1;
    360   1.1  christos 
    361   1.1  christos   /* Search back.  */
    362   1.1  christos   while (1)
    363   1.1  christos     {
    364   1.1  christos       if (addr < 4)
    365   1.1  christos 	return -1;
    366   1.1  christos 
    367   1.1  christos       /* Check previous 2 instructions.  */
    368   1.1  christos       ip2k_get_mem (abfd, contents + addr - 4, 4, code);
    369   1.1  christos       if ((IS_ADD_W_WREG_OPCODE (code + 0))
    370   1.1  christos 	  && (IS_ADD_PCL_W_OPCODE (code + 2)))
    371   1.1  christos 	return table_index;
    372   1.1  christos 
    373   1.1  christos       if ((! IS_PAGE_OPCODE (code + 0))
    374   1.1  christos 	  || (! IS_JMP_OPCODE (code + 2)))
    375   1.1  christos 	return -1;
    376   1.1  christos 
    377   1.1  christos       table_index++;
    378   1.1  christos       addr -= 4;
    379   1.1  christos     }
    380   1.1  christos }
    381   1.1  christos 
    382   1.1  christos /* Determine if the instruction sequence matches that for
    383   1.1  christos    the prologue switch dispatch table with fewer than
    384   1.1  christos    256 entries but more than 127.
    385   1.1  christos 
    386   1.1  christos    Before relaxation.
    387   1.8  christos 	  push	  %lo8insn(label) ; Push address of table
    388   1.8  christos 	  push	  %hi8insn(label)
    389   1.8  christos 	  add	  w,wreg	  ; index*2 => offset
    390   1.8  christos 	  snc			  ; CARRY SET?
    391   1.8  christos 	  inc	  1(sp)		  ; Propagate MSB into table address
    392   1.8  christos 	  add	  2(sp),w	  ; Add low bits of offset to table address
    393   1.8  christos 	  snc			  ; and handle any carry-out
    394   1.8  christos 	  inc	  1(sp)
    395   1.1  christos    addr=>
    396   1.8  christos 	  page	  __indjmp	  ; Do an indirect jump to that location
    397   1.8  christos 	  jmp	  __indjmp
    398   1.8  christos    label:			  ; case dispatch table starts here
    399   1.8  christos 	   page	   $nnn1
    400   1.8  christos 	   jmp	   $nnn1
    401   1.8  christos 	   page	   $nnn2
    402   1.8  christos 	   jmp	   $nnn2
    403   1.8  christos 	   ...
    404   1.8  christos 	   page	   $nnnN
    405   1.8  christos 	   jmp	   $nnnN
    406   1.1  christos 
    407   1.1  christos   After relaxation.
    408   1.8  christos 	  push	  %lo8insn(label) ; Push address of table
    409   1.8  christos 	  push	  %hi8insn(label)
    410   1.8  christos 	  add	  2(sp),w	  ; Add low bits of offset to table address
    411   1.8  christos 	  snc			  ; and handle any carry-out
    412   1.8  christos 	  inc	  1(sp)
    413   1.1  christos   addr=>
    414   1.8  christos 	  page	  __indjmp	  ; Do an indirect jump to that location
    415   1.8  christos 	  jmp	  __indjmp
    416   1.8  christos    label:			  ; case dispatch table starts here
    417   1.8  christos 	  jmp	  $nnn1
    418   1.8  christos 	  jmp	  $nnn2
    419   1.8  christos 	  ...
    420   1.8  christos 	  jmp	  $nnnN  */
    421   1.1  christos 
    422   1.1  christos static int
    423   1.1  christos ip2k_is_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
    424   1.1  christos 			  asection *sec,
    425   1.1  christos 			  bfd_vma addr,
    426   1.1  christos 			  bfd_byte *contents)
    427   1.1  christos {
    428   1.1  christos   bfd_byte code[16];
    429   1.1  christos   int table_index = 0;
    430   1.1  christos 
    431   1.1  christos   /* Check current page-jmp.  */
    432   1.1  christos   if (addr + 4 > sec->size)
    433   1.1  christos     return -1;
    434   1.1  christos 
    435   1.1  christos   ip2k_get_mem (abfd, contents + addr, 4, code);
    436   1.1  christos   if ((! IS_PAGE_OPCODE (code + 0))
    437   1.1  christos       || (! IS_JMP_OPCODE (code + 2)))
    438   1.1  christos     return -1;
    439   1.1  christos 
    440   1.1  christos   /* Search back.  */
    441   1.1  christos   while (1)
    442   1.1  christos     {
    443   1.1  christos       if (addr < 16)
    444   1.1  christos 	return -1;
    445   1.1  christos 
    446   1.1  christos       /* Check previous 8 instructions.  */
    447   1.1  christos       ip2k_get_mem (abfd, contents + addr - 16, 16, code);
    448   1.1  christos       if ((IS_ADD_W_WREG_OPCODE (code + 0))
    449   1.1  christos 	  && (IS_SNC_OPCODE (code + 2))
    450   1.1  christos 	  && (IS_INC_1SP_OPCODE (code + 4))
    451   1.1  christos 	  && (IS_ADD_2SP_W_OPCODE (code + 6))
    452   1.1  christos 	  && (IS_SNC_OPCODE (code + 8))
    453   1.1  christos 	  && (IS_INC_1SP_OPCODE (code + 10))
    454   1.1  christos 	  && (IS_PAGE_OPCODE (code + 12))
    455   1.1  christos 	  && (IS_JMP_OPCODE (code + 14)))
    456   1.1  christos 	return table_index;
    457   1.1  christos 
    458   1.1  christos       if ((IS_ADD_W_WREG_OPCODE (code + 2))
    459   1.1  christos 	  && (IS_SNC_OPCODE (code + 4))
    460   1.1  christos 	  && (IS_INC_1SP_OPCODE (code + 6))
    461   1.1  christos 	  && (IS_ADD_2SP_W_OPCODE (code + 8))
    462   1.1  christos 	  && (IS_SNC_OPCODE (code + 10))
    463   1.1  christos 	  && (IS_INC_1SP_OPCODE (code + 12))
    464   1.1  christos 	  && (IS_JMP_OPCODE (code + 14)))
    465   1.1  christos 	return table_index;
    466   1.1  christos 
    467   1.1  christos       if ((! IS_PAGE_OPCODE (code + 0))
    468   1.1  christos 	  || (! IS_JMP_OPCODE (code + 2)))
    469   1.1  christos 	return -1;
    470   1.1  christos 
    471   1.1  christos       table_index++;
    472   1.1  christos       addr -= 4;
    473   1.1  christos     }
    474   1.1  christos }
    475   1.1  christos 
    476   1.1  christos /* Returns the expected page state for the given instruction not including
    477   1.1  christos    the effect of page instructions.  */
    478   1.1  christos 
    479   1.1  christos static bfd_vma
    480   1.1  christos ip2k_nominal_page_bits (bfd *abfd ATTRIBUTE_UNUSED,
    481   1.1  christos 			asection *sec,
    482   1.1  christos 			bfd_vma addr,
    483   1.1  christos 			bfd_byte *contents)
    484   1.1  christos {
    485   1.1  christos   bfd_vma page = PAGENO (BASEADDR (sec) + addr);
    486   1.1  christos 
    487   1.1  christos   /* Check if section flows into this page. If not then the page
    488   1.1  christos      bits are assumed to match the PC. This will be true unless
    489   1.1  christos      the user has a page instruction without a call/jump, in which
    490   1.1  christos      case they are on their own.  */
    491   1.1  christos   if (PAGENO (BASEADDR (sec)) == page)
    492   1.1  christos     return page;
    493   1.1  christos 
    494   1.1  christos   /* Section flows across page boundary. The page bits should match
    495   1.1  christos      the PC unless there is a possible flow from the previous page,
    496   1.1  christos      in which case it is not possible to determine the value of the
    497   1.1  christos      page bits.  */
    498   1.1  christos   while (PAGENO (BASEADDR (sec) + addr - 2) == page)
    499   1.1  christos     {
    500   1.1  christos       bfd_byte code[2];
    501   1.1  christos 
    502   1.1  christos       addr -= 2;
    503   1.1  christos       ip2k_get_mem (abfd, contents + addr, 2, code);
    504   1.1  christos       if (!IS_PAGE_OPCODE (code))
    505   1.1  christos 	continue;
    506   1.1  christos 
    507   1.1  christos       /* Found a page instruction, check if jump table.  */
    508   1.1  christos       if (ip2k_is_switch_table_128 (abfd, sec, addr, contents) != -1)
    509   1.1  christos 	/* Jump table => page is conditional.  */
    510   1.1  christos 	continue;
    511   1.1  christos 
    512   1.1  christos       if (ip2k_is_switch_table_256 (abfd, sec, addr, contents) != -1)
    513   1.1  christos 	/* Jump table => page is conditional.  */
    514   1.1  christos 	continue;
    515   1.1  christos 
    516   1.1  christos       /* Found a page instruction, check if conditional.  */
    517   1.1  christos       if (addr >= 2)
    518   1.8  christos 	{
    519   1.1  christos 	  ip2k_get_mem (abfd, contents + addr - 2, 2, code);
    520   1.8  christos 	  if (IS_SKIP_OPCODE (code))
    521   1.1  christos 	    /* Page is conditional.  */
    522   1.1  christos 	    continue;
    523   1.8  christos 	}
    524   1.1  christos 
    525   1.1  christos       /* Unconditional page instruction => page bits should be correct.  */
    526   1.1  christos       return page;
    527   1.1  christos     }
    528   1.1  christos 
    529   1.1  christos   /* Flow from previous page => page bits are impossible to determine.  */
    530   1.1  christos   return 0;
    531   1.1  christos }
    532   1.1  christos 
    533  1.10  christos static bool
    534   1.1  christos ip2k_test_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
    535   1.1  christos 		     asection *sec,
    536   1.1  christos 		     Elf_Internal_Rela *irel,
    537   1.1  christos 		     struct misc *misc)
    538   1.1  christos {
    539   1.1  christos   bfd_vma symval;
    540   1.1  christos 
    541   1.1  christos   /* Get the value of the symbol referred to by the reloc.  */
    542   1.1  christos   symval = symbol_value (abfd, misc->symtab_hdr, misc->isymbuf, irel);
    543   1.1  christos   if (symval == UNDEFINED_SYMBOL)
    544   1.1  christos     /* This appears to be a reference to an undefined
    545   1.1  christos        symbol.  Just ignore it--it will be caught by the
    546   1.1  christos        regular reloc processing.  */
    547  1.10  christos     return false;
    548   1.1  christos 
    549   1.1  christos   /* Test if we can delete this page instruction.  */
    550   1.1  christos   if (PAGENO (symval + irel->r_addend) !=
    551   1.1  christos       ip2k_nominal_page_bits (abfd, sec, irel->r_offset, misc->contents))
    552  1.10  christos     return false;
    553   1.1  christos 
    554  1.10  christos   return true;
    555   1.1  christos }
    556   1.1  christos 
    557   1.1  christos /* Parts of a Stabs entry.  */
    558   1.1  christos 
    559   1.1  christos #define STRDXOFF   0
    560   1.1  christos #define TYPEOFF    4
    561   1.1  christos #define OTHEROFF   5
    562   1.1  christos #define DESCOFF    6
    563   1.1  christos #define VALOFF     8
    564   1.1  christos #define STABSIZE   12
    565   1.1  christos 
    566   1.1  christos /* Adjust all the relocations entries after adding or inserting instructions.  */
    567   1.1  christos 
    568   1.1  christos static void
    569   1.1  christos adjust_all_relocations (bfd *abfd,
    570   1.1  christos 			asection *sec,
    571   1.1  christos 			bfd_vma addr,
    572   1.1  christos 			bfd_vma endaddr,
    573   1.1  christos 			int count,
    574   1.1  christos 			int noadj)
    575   1.1  christos {
    576   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
    577   1.1  christos   Elf_Internal_Sym *isymbuf, *isym, *isymend;
    578   1.1  christos   unsigned int shndx;
    579   1.1  christos   Elf_Internal_Rela *irel, *irelend, *irelbase;
    580   1.1  christos   struct elf_link_hash_entry **sym_hashes;
    581   1.1  christos   struct elf_link_hash_entry **end_hashes;
    582   1.1  christos   unsigned int symcount;
    583   1.1  christos   asection *stab;
    584   1.1  christos 
    585   1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
    586   1.1  christos   isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
    587   1.1  christos 
    588   1.1  christos   shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
    589   1.1  christos 
    590   1.1  christos   irelbase = elf_section_data (sec)->relocs;
    591   1.1  christos   irelend = irelbase + sec->reloc_count;
    592   1.1  christos 
    593   1.1  christos   for (irel = irelbase; irel < irelend; irel++)
    594   1.1  christos     {
    595   1.1  christos       if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
    596   1.8  christos 	{
    597   1.8  christos 	  /* Get the value of the symbol referred to by the reloc.  */
    598   1.8  christos 	  if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    599   1.8  christos 	    {
    600   1.8  christos 	      asection *sym_sec;
    601   1.1  christos 
    602   1.8  christos 	      /* A local symbol.  */
    603   1.1  christos 	      isym = isymbuf + ELF32_R_SYM (irel->r_info);
    604   1.8  christos 	      sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
    605   1.1  christos 
    606   1.8  christos 	      if (isym->st_shndx == shndx)
    607   1.8  christos 		{
    608   1.8  christos 		  bfd_vma baseaddr = BASEADDR (sec);
    609   1.8  christos 		  bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
    610   1.8  christos 				   + irel->r_addend;
    611   1.8  christos 
    612   1.8  christos 		  if ((baseaddr + addr + noadj) <= symval
    613   1.8  christos 		      && symval < (baseaddr + endaddr))
    614   1.8  christos 		    irel->r_addend += count;
    615   1.8  christos 		}
    616   1.8  christos 	    }
    617   1.8  christos 	}
    618   1.1  christos 
    619   1.1  christos       /* Do this only for PC space relocations.  */
    620   1.1  christos       if (addr <= irel->r_offset && irel->r_offset < endaddr)
    621   1.8  christos 	irel->r_offset += count;
    622   1.1  christos     }
    623   1.1  christos 
    624   1.1  christos   /* Now fix the stab relocations.  */
    625   1.1  christos   stab = bfd_get_section_by_name (abfd, ".stab");
    626  1.11  christos   if (stab && stab->reloc_count != 0)
    627   1.1  christos     {
    628   1.1  christos       bfd_byte *stabcontents, *stabend, *stabp;
    629   1.1  christos       bfd_size_type stab_size = stab->rawsize ? stab->rawsize : stab->size;
    630   1.1  christos 
    631   1.1  christos       irelbase = elf_section_data (stab)->relocs;
    632   1.1  christos       irelend = irelbase + stab->reloc_count;
    633   1.1  christos 
    634   1.1  christos       /* Pull out the contents of the stab section.  */
    635   1.1  christos       if (elf_section_data (stab)->this_hdr.contents != NULL)
    636   1.1  christos 	stabcontents = elf_section_data (stab)->this_hdr.contents;
    637   1.1  christos       else
    638   1.1  christos 	{
    639   1.1  christos 	  if (!bfd_malloc_and_get_section (abfd, stab, &stabcontents))
    640   1.1  christos 	    {
    641   1.9  christos 	      free (stabcontents);
    642   1.1  christos 	      return;
    643   1.1  christos 	    }
    644   1.1  christos 
    645   1.1  christos 	  /* We need to remember this.  */
    646   1.1  christos 	  elf_section_data (stab)->this_hdr.contents = stabcontents;
    647   1.1  christos 	}
    648   1.1  christos 
    649   1.1  christos       stabend = stabcontents + stab_size;
    650   1.1  christos 
    651   1.1  christos       for (irel = irelbase; irel < irelend; irel++)
    652   1.1  christos 	{
    653   1.1  christos 	  if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
    654   1.1  christos 	    {
    655   1.1  christos 	      /* Get the value of the symbol referred to by the reloc.  */
    656   1.1  christos 	      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    657   1.1  christos 		{
    658   1.1  christos 		  asection *sym_sec;
    659   1.1  christos 
    660   1.1  christos 		  /* A local symbol.  */
    661   1.1  christos 		  isym = isymbuf + ELF32_R_SYM (irel->r_info);
    662   1.1  christos 		  sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
    663   1.1  christos 
    664   1.1  christos 		  if (sym_sec == sec)
    665   1.1  christos 		    {
    666   1.1  christos 		      const char *name;
    667   1.1  christos 		      unsigned char type;
    668   1.1  christos 		      bfd_vma value;
    669   1.1  christos 		      bfd_vma baseaddr = BASEADDR (sec);
    670   1.1  christos 		      bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
    671   1.1  christos 			+ irel->r_addend;
    672   1.1  christos 
    673   1.1  christos 		      if ((baseaddr + addr) <= symval
    674   1.1  christos 			  && symval <= (baseaddr + endaddr))
    675   1.1  christos 			irel->r_addend += count;
    676   1.1  christos 
    677   1.1  christos 		      /* Go hunt up a function and fix its line info if needed.  */
    678   1.1  christos 		      stabp = stabcontents + irel->r_offset - 8;
    679   1.1  christos 
    680   1.1  christos 		      /* Go pullout the stab entry.  */
    681   1.1  christos 		      type  = bfd_h_get_8 (abfd, stabp + TYPEOFF);
    682   1.1  christos 		      value = bfd_h_get_32 (abfd, stabp + VALOFF);
    683   1.1  christos 
    684   1.1  christos 		      name = bfd_get_stab_name (type);
    685   1.1  christos 
    686   1.1  christos 		      if (strcmp (name, "FUN") == 0)
    687   1.1  christos 			{
    688   1.1  christos 			  int function_adjusted = 0;
    689   1.1  christos 
    690   1.1  christos 			  if (symval > (baseaddr + addr))
    691   1.1  christos 			    /* Not in this function.  */
    692   1.1  christos 			    continue;
    693   1.1  christos 
    694   1.1  christos 			  /* Hey we got a function hit.  */
    695   1.1  christos 			  stabp += STABSIZE;
    696   1.1  christos 			  for (;stabp < stabend; stabp += STABSIZE)
    697   1.1  christos 			    {
    698   1.1  christos 			      /* Go pullout the stab entry.  */
    699   1.1  christos 			      type  = bfd_h_get_8 (abfd, stabp + TYPEOFF);
    700   1.1  christos 			      value = bfd_h_get_32 (abfd, stabp + VALOFF);
    701   1.1  christos 
    702   1.1  christos 			      name = bfd_get_stab_name (type);
    703   1.1  christos 
    704   1.1  christos 			      if (strcmp (name, "FUN") == 0)
    705   1.1  christos 				{
    706   1.1  christos 				  /* Hit another function entry.  */
    707   1.1  christos 				  if (function_adjusted)
    708   1.1  christos 				    {
    709   1.1  christos 				      /* Adjust the value.  */
    710   1.1  christos 				      value += count;
    711   1.1  christos 
    712   1.1  christos 				      /* We need to put it back.  */
    713   1.1  christos 				      bfd_h_put_32 (abfd, value,stabp + VALOFF);
    714   1.1  christos 				    }
    715   1.1  christos 
    716   1.1  christos 				  /* And then bale out.  */
    717   1.1  christos 				  break;
    718   1.1  christos 				}
    719   1.1  christos 
    720   1.1  christos 			      if (strcmp (name, "SLINE") == 0)
    721   1.1  christos 				{
    722   1.1  christos 				  /* Got a line entry.  */
    723   1.1  christos 				  if ((baseaddr + addr) <= (symval + value))
    724   1.1  christos 				    {
    725   1.1  christos 				      /* Adjust the line entry.  */
    726   1.1  christos 				      value += count;
    727   1.1  christos 
    728   1.1  christos 				      /* We need to put it back.  */
    729   1.1  christos 				      bfd_h_put_32 (abfd, value,stabp + VALOFF);
    730   1.1  christos 				      function_adjusted = 1;
    731   1.1  christos 				    }
    732   1.1  christos 				}
    733   1.1  christos 			    }
    734   1.1  christos 			}
    735   1.1  christos 		    }
    736   1.1  christos 		}
    737   1.1  christos 	    }
    738   1.1  christos 	}
    739   1.1  christos     }
    740   1.1  christos 
    741   1.1  christos   /* When adding an instruction back it is sometimes necessary to move any
    742   1.1  christos      global or local symbol that was referencing the first instruction of
    743   1.1  christos      the moved block to refer to the first instruction of the inserted block.
    744   1.1  christos 
    745   1.1  christos      For example adding a PAGE instruction before a CALL or JMP requires
    746   1.1  christos      that any label on the CALL or JMP is moved to the PAGE insn.  */
    747   1.1  christos   addr += noadj;
    748   1.1  christos 
    749   1.1  christos   /* Adjust the local symbols defined in this section.  */
    750   1.1  christos   isymend = isymbuf + symtab_hdr->sh_info;
    751   1.1  christos   for (isym = isymbuf; isym < isymend; isym++)
    752   1.1  christos     {
    753   1.1  christos       if (isym->st_shndx == shndx
    754   1.1  christos 	  && addr <= isym->st_value
    755   1.1  christos 	  && isym->st_value < endaddr)
    756   1.1  christos 	isym->st_value += count;
    757   1.1  christos     }
    758   1.1  christos 
    759   1.1  christos   /* Now adjust the global symbols defined in this section.  */
    760   1.1  christos   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
    761   1.1  christos 	      - symtab_hdr->sh_info);
    762   1.1  christos   sym_hashes = elf_sym_hashes (abfd);
    763   1.1  christos   end_hashes = sym_hashes + symcount;
    764   1.1  christos   for (; sym_hashes < end_hashes; sym_hashes++)
    765   1.1  christos     {
    766   1.1  christos       struct elf_link_hash_entry *sym_hash = *sym_hashes;
    767   1.1  christos 
    768   1.1  christos       if ((sym_hash->root.type == bfd_link_hash_defined
    769   1.1  christos 	   || sym_hash->root.type == bfd_link_hash_defweak)
    770   1.1  christos 	  && sym_hash->root.u.def.section == sec)
    771   1.1  christos 	{
    772   1.8  christos 	  if (addr <= sym_hash->root.u.def.value
    773   1.8  christos 	      && sym_hash->root.u.def.value < endaddr)
    774   1.1  christos 	    sym_hash->root.u.def.value += count;
    775   1.1  christos 	}
    776   1.1  christos     }
    777   1.1  christos 
    778   1.1  christos   return;
    779   1.1  christos }
    780   1.1  christos 
    781   1.1  christos /* Delete some bytes from a section while relaxing.  */
    782   1.1  christos 
    783  1.10  christos static bool
    784   1.1  christos ip2k_elf_relax_delete_bytes (bfd *abfd,
    785   1.1  christos 			     asection *sec,
    786   1.1  christos 			     bfd_vma addr,
    787   1.1  christos 			     int count)
    788   1.1  christos {
    789   1.1  christos   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
    790   1.1  christos   bfd_vma endaddr = sec->size;
    791   1.1  christos 
    792   1.1  christos   /* Actually delete the bytes.  */
    793   1.1  christos   memmove (contents + addr, contents + addr + count,
    794   1.1  christos 	   endaddr - addr - count);
    795   1.1  christos 
    796   1.1  christos   sec->size -= count;
    797   1.1  christos 
    798   1.1  christos   adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0);
    799  1.10  christos   return true;
    800   1.1  christos }
    801   1.1  christos 
    802  1.10  christos static bool
    803   1.1  christos ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
    804   1.1  christos 		       asection *sec,
    805   1.1  christos 		       Elf_Internal_Rela *irel,
    806  1.10  christos 		       bool *again,
    807   1.1  christos 		       struct misc *misc)
    808   1.1  christos {
    809   1.1  christos   /* Note that we've changed the relocs, section contents, etc.  */
    810   1.1  christos   elf_section_data (sec)->relocs = misc->irelbase;
    811   1.1  christos   elf_section_data (sec)->this_hdr.contents = misc->contents;
    812   1.1  christos   misc->symtab_hdr->contents = (bfd_byte *) misc->isymbuf;
    813   1.1  christos 
    814   1.1  christos   /* Fix the relocation's type.  */
    815   1.1  christos   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_IP2K_NONE);
    816   1.1  christos 
    817   1.1  christos   /* Delete the PAGE insn.  */
    818   1.1  christos   if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
    819  1.10  christos     return false;
    820   1.1  christos 
    821   1.1  christos   /* Modified => will need to iterate relaxation again.  */
    822  1.10  christos   *again = true;
    823   1.1  christos 
    824  1.10  christos   return true;
    825   1.1  christos }
    826   1.1  christos 
    827  1.10  christos static bool
    828   1.1  christos ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
    829   1.1  christos 			     asection *sec,
    830   1.1  christos 			     Elf_Internal_Rela *irel,
    831  1.10  christos 			     bool *again,
    832   1.1  christos 			     struct misc *misc)
    833   1.1  christos {
    834   1.1  christos   Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
    835   1.1  christos   Elf_Internal_Rela *ireltest = irel;
    836   1.1  christos   bfd_byte code[4];
    837   1.1  christos   bfd_vma addr;
    838   1.1  christos 
    839   1.1  christos   /* Test all page instructions.  */
    840   1.1  christos   addr = irel->r_offset;
    841   1.1  christos   while (1)
    842   1.1  christos     {
    843   1.1  christos       if (addr + 4 > sec->size)
    844   1.1  christos 	break;
    845   1.1  christos 
    846   1.1  christos       ip2k_get_mem (abfd, misc->contents + addr, 4, code);
    847   1.1  christos       if ((! IS_PAGE_OPCODE (code + 0))
    848   1.1  christos 	  || (! IS_JMP_OPCODE (code + 2)))
    849   1.1  christos 	break;
    850   1.1  christos 
    851   1.1  christos       /* Validate relocation entry (every entry should have a matching
    852   1.8  christos 	  relocation entry).  */
    853   1.1  christos       if (ireltest >= irelend)
    854   1.8  christos 	{
    855   1.1  christos 	  _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
    856  1.10  christos 	  return false;
    857   1.8  christos 	}
    858   1.1  christos 
    859   1.1  christos       if (ireltest->r_offset != addr)
    860   1.8  christos 	{
    861   1.1  christos 	  _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
    862  1.10  christos 	  return false;
    863   1.8  christos 	}
    864   1.1  christos 
    865   1.1  christos       if (! ip2k_test_page_insn (abfd, sec, ireltest, misc))
    866   1.1  christos 	/* Un-removable page insn => nothing can be done.  */
    867  1.10  christos 	return true;
    868   1.1  christos 
    869   1.1  christos       addr += 4;
    870   1.1  christos       ireltest += 2;
    871   1.1  christos     }
    872   1.1  christos 
    873   1.1  christos   /* Relaxable. Adjust table header.  */
    874   1.1  christos   ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 4, code);
    875   1.1  christos   if ((! IS_ADD_W_WREG_OPCODE (code + 0))
    876   1.1  christos       || (! IS_ADD_PCL_W_OPCODE (code + 2)))
    877   1.1  christos     {
    878   1.1  christos       _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
    879  1.10  christos       return false;
    880   1.1  christos     }
    881   1.1  christos 
    882   1.1  christos   if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset - 4, 2))
    883  1.10  christos     return false;
    884   1.1  christos 
    885  1.10  christos   *again = true;
    886   1.1  christos 
    887   1.1  christos   /* Delete all page instructions in table.  */
    888   1.1  christos   while (irel < ireltest)
    889   1.1  christos     {
    890   1.1  christos       if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
    891  1.10  christos 	return false;
    892   1.1  christos       irel += 2;
    893   1.1  christos     }
    894   1.1  christos 
    895  1.10  christos   return true;
    896   1.1  christos }
    897   1.1  christos 
    898  1.10  christos static bool
    899   1.1  christos ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
    900   1.1  christos 			     asection *sec,
    901   1.1  christos 			     Elf_Internal_Rela *irel,
    902  1.10  christos 			     bool *again,
    903   1.1  christos 			     struct misc *misc)
    904   1.1  christos {
    905   1.1  christos   Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
    906   1.1  christos   Elf_Internal_Rela *ireltest = irel;
    907   1.1  christos   bfd_byte code[12];
    908   1.1  christos   bfd_vma addr;
    909   1.1  christos 
    910   1.1  christos   /* Test all page instructions.  */
    911   1.1  christos   addr = irel->r_offset;
    912   1.1  christos 
    913   1.1  christos   while (1)
    914   1.1  christos     {
    915   1.1  christos       if (addr + 4 > sec->size)
    916   1.1  christos 	break;
    917   1.1  christos 
    918   1.1  christos       ip2k_get_mem (abfd, misc->contents + addr, 4, code);
    919   1.1  christos 
    920   1.1  christos       if ((! IS_PAGE_OPCODE (code + 0))
    921   1.1  christos 	  || (! IS_JMP_OPCODE (code + 2)))
    922   1.1  christos 	break;
    923   1.1  christos 
    924   1.1  christos       /* Validate relocation entry (every entry should have a matching
    925   1.8  christos 	  relocation entry).  */
    926   1.1  christos       if (ireltest >= irelend)
    927   1.8  christos 	{
    928   1.8  christos 	  _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
    929  1.10  christos 	  return false;
    930   1.8  christos 	}
    931   1.1  christos 
    932   1.1  christos       if (ireltest->r_offset != addr)
    933   1.8  christos 	{
    934   1.8  christos 	  _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
    935  1.10  christos 	  return false;
    936   1.8  christos 	}
    937   1.1  christos 
    938   1.1  christos       if (!ip2k_test_page_insn (abfd, sec, ireltest, misc))
    939   1.1  christos 	/* Un-removable page insn => nothing can be done.  */
    940  1.10  christos 	return true;
    941   1.1  christos 
    942   1.1  christos       addr += 4;
    943   1.1  christos       ireltest += 2;
    944   1.1  christos     }
    945   1.1  christos 
    946   1.1  christos   /* Relaxable. Adjust table header.  */
    947   1.1  christos   ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 2, code);
    948   1.1  christos   if (IS_PAGE_OPCODE (code))
    949   1.1  christos     addr = irel->r_offset - 16;
    950   1.1  christos   else
    951   1.1  christos     addr = irel->r_offset - 14;
    952   1.1  christos 
    953   1.1  christos   ip2k_get_mem (abfd, misc->contents + addr, 12, code);
    954   1.1  christos   if ((!IS_ADD_W_WREG_OPCODE (code + 0))
    955   1.1  christos       || (!IS_SNC_OPCODE (code + 2))
    956   1.1  christos       || (!IS_INC_1SP_OPCODE (code + 4))
    957   1.1  christos       || (!IS_ADD_2SP_W_OPCODE (code + 6))
    958   1.1  christos       || (!IS_SNC_OPCODE (code + 8))
    959   1.1  christos       || (!IS_INC_1SP_OPCODE (code + 10)))
    960   1.1  christos     {
    961   1.1  christos       _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
    962  1.10  christos       return false;
    963   1.1  christos     }
    964   1.1  christos 
    965   1.1  christos   /* Delete first 3 opcodes.  */
    966   1.1  christos   if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6))
    967  1.10  christos     return false;
    968   1.1  christos 
    969  1.10  christos   *again = true;
    970   1.1  christos 
    971   1.1  christos   /* Delete all page instructions in table.  */
    972   1.1  christos   while (irel < ireltest)
    973   1.1  christos     {
    974   1.1  christos       if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
    975  1.10  christos 	return false;
    976   1.1  christos       irel += 2;
    977   1.1  christos     }
    978   1.1  christos 
    979  1.10  christos   return true;
    980   1.1  christos }
    981   1.1  christos 
    982   1.1  christos /* This function handles relaxation of a section in a specific page.  */
    983   1.1  christos 
    984  1.10  christos static bool
    985   1.1  christos ip2k_elf_relax_section_page (bfd *abfd,
    986   1.1  christos 			     asection *sec,
    987  1.10  christos 			     bool *again,
    988   1.1  christos 			     struct misc *misc,
    989   1.1  christos 			     unsigned long page_start,
    990   1.1  christos 			     unsigned long page_end)
    991   1.1  christos {
    992   1.1  christos   Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
    993   1.1  christos   Elf_Internal_Rela *irel;
    994   1.1  christos   int switch_table_128;
    995   1.1  christos   int switch_table_256;
    996   1.1  christos 
    997   1.1  christos   /* Walk thru the section looking for relaxation opportunities.  */
    998   1.1  christos   for (irel = misc->irelbase; irel < irelend; irel++)
    999   1.1  christos     {
   1000   1.1  christos       if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3)
   1001   1.1  christos 	/* Ignore non page instructions.  */
   1002   1.1  christos 	continue;
   1003   1.1  christos 
   1004   1.1  christos       if (BASEADDR (sec) + irel->r_offset < page_start)
   1005   1.1  christos 	/* Ignore page instructions on earlier page - they have
   1006   1.1  christos 	   already been processed. Remember that there is code flow
   1007   1.1  christos 	   that crosses a page boundary.  */
   1008   1.1  christos 	continue;
   1009   1.1  christos 
   1010   1.1  christos       if (BASEADDR (sec) + irel->r_offset > page_end)
   1011   1.1  christos 	/* Flow beyond end of page => nothing more to do for this page.  */
   1012  1.10  christos 	return true;
   1013   1.1  christos 
   1014   1.1  christos       /* Detect switch tables.  */
   1015   1.1  christos       switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents);
   1016   1.1  christos       switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents);
   1017   1.1  christos 
   1018   1.1  christos       if ((switch_table_128 > 0) || (switch_table_256 > 0))
   1019   1.1  christos 	/* If the index is greater than 0 then it has already been processed.  */
   1020   1.1  christos 	continue;
   1021   1.1  christos 
   1022   1.1  christos       if (switch_table_128 == 0)
   1023   1.1  christos 	{
   1024   1.1  christos 	  if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc))
   1025  1.10  christos 	    return false;
   1026   1.1  christos 
   1027   1.1  christos 	  continue;
   1028   1.1  christos 	}
   1029   1.1  christos 
   1030   1.1  christos       if (switch_table_256 == 0)
   1031   1.1  christos 	{
   1032   1.1  christos 	  if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc))
   1033  1.10  christos 	    return false;
   1034   1.1  christos 
   1035   1.1  christos 	  continue;
   1036   1.1  christos 	}
   1037   1.1  christos 
   1038   1.1  christos       /* Simple relax.  */
   1039   1.1  christos       if (ip2k_test_page_insn (abfd, sec, irel, misc))
   1040   1.1  christos 	{
   1041   1.1  christos 	  if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
   1042  1.10  christos 	    return false;
   1043   1.1  christos 
   1044   1.1  christos 	  continue;
   1045   1.1  christos 	}
   1046   1.1  christos     }
   1047   1.1  christos 
   1048  1.10  christos   return true;
   1049   1.1  christos }
   1050   1.1  christos 
   1051   1.1  christos /* This function handles relaxing for the ip2k.
   1052   1.1  christos 
   1053   1.1  christos    Principle: Start with the first page and remove page instructions that
   1054   1.1  christos    are not require on this first page. By removing page instructions more
   1055   1.1  christos    code will fit into this page - repeat until nothing more can be achieved
   1056   1.1  christos    for this page. Move on to the next page.
   1057   1.1  christos 
   1058   1.1  christos    Processing the pages one at a time from the lowest page allows a removal
   1059   1.1  christos    only policy to be used - pages can be removed but are never reinserted.  */
   1060   1.1  christos 
   1061  1.10  christos static bool
   1062   1.1  christos ip2k_elf_relax_section (bfd *abfd,
   1063   1.1  christos 			asection *sec,
   1064   1.1  christos 			struct bfd_link_info *link_info,
   1065  1.10  christos 			bool *again)
   1066   1.1  christos {
   1067   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1068   1.1  christos   Elf_Internal_Rela *internal_relocs;
   1069   1.1  christos   bfd_byte *contents = NULL;
   1070   1.1  christos   Elf_Internal_Sym *isymbuf = NULL;
   1071   1.1  christos   static asection * first_section = NULL;
   1072   1.1  christos   static unsigned long search_addr;
   1073   1.1  christos   static unsigned long page_start = 0;
   1074   1.1  christos   static unsigned long page_end = 0;
   1075   1.1  christos   static unsigned int pass = 0;
   1076  1.10  christos   static bool new_pass = false;
   1077  1.10  christos   static bool changed = false;
   1078   1.1  christos   struct misc misc;
   1079   1.1  christos 
   1080   1.1  christos   /* Assume nothing changes.  */
   1081  1.10  christos   *again = false;
   1082   1.1  christos 
   1083   1.1  christos   if (first_section == NULL)
   1084   1.1  christos     {
   1085  1.10  christos       ip2k_relaxed = true;
   1086   1.1  christos       first_section = sec;
   1087   1.1  christos     }
   1088   1.1  christos 
   1089   1.1  christos   if (first_section == sec)
   1090   1.1  christos     {
   1091   1.1  christos       pass++;
   1092  1.10  christos       new_pass = true;
   1093   1.1  christos     }
   1094   1.1  christos 
   1095   1.1  christos   /* We don't have to do anything for a relocatable link,
   1096   1.1  christos      if this section does not have relocs, or if this is
   1097   1.1  christos      not a code section.  */
   1098   1.6  christos   if (bfd_link_relocatable (link_info)
   1099  1.11  christos       || sec->reloc_count == 0
   1100   1.1  christos       || (sec->flags & SEC_RELOC) == 0
   1101  1.11  christos       || (sec->flags & SEC_HAS_CONTENTS) == 0
   1102   1.1  christos       || (sec->flags & SEC_CODE) == 0)
   1103  1.10  christos     return true;
   1104   1.1  christos 
   1105   1.1  christos   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   1106   1.1  christos 
   1107   1.1  christos   internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
   1108   1.1  christos 					       link_info->keep_memory);
   1109   1.1  christos   if (internal_relocs == NULL)
   1110   1.1  christos     goto error_return;
   1111   1.1  christos 
   1112   1.1  christos   /* Get section contents cached copy if it exists.  */
   1113   1.1  christos   if (contents == NULL)
   1114   1.1  christos     {
   1115   1.1  christos       /* Get cached copy if it exists.  */
   1116   1.1  christos       if (elf_section_data (sec)->this_hdr.contents != NULL)
   1117   1.1  christos 	contents = elf_section_data (sec)->this_hdr.contents;
   1118   1.1  christos       else
   1119   1.1  christos 	{
   1120   1.1  christos 	  /* Go get them off disk.  */
   1121   1.1  christos 	  if (!bfd_malloc_and_get_section (abfd, sec, &contents))
   1122   1.1  christos 	    goto error_return;
   1123   1.1  christos 	}
   1124   1.1  christos     }
   1125   1.1  christos 
   1126   1.1  christos   /* Read this BFD's symbols cached copy if it exists.  */
   1127   1.1  christos   if (isymbuf == NULL && symtab_hdr->sh_info != 0)
   1128   1.1  christos     {
   1129   1.1  christos       isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
   1130   1.1  christos       if (isymbuf == NULL)
   1131   1.1  christos 	isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
   1132   1.1  christos 					symtab_hdr->sh_info, 0,
   1133   1.1  christos 					NULL, NULL, NULL);
   1134   1.1  christos       if (isymbuf == NULL)
   1135   1.1  christos 	goto error_return;
   1136   1.1  christos     }
   1137   1.1  christos 
   1138   1.1  christos   misc.symtab_hdr = symtab_hdr;
   1139   1.1  christos   misc.isymbuf = isymbuf;
   1140   1.1  christos   misc.irelbase = internal_relocs;
   1141   1.1  christos   misc.contents = contents;
   1142   1.1  christos 
   1143   1.1  christos   /* This is where all the relaxation actually get done.  */
   1144   1.1  christos   if ((pass == 1) || (new_pass && !changed))
   1145   1.1  christos     {
   1146   1.1  christos       /* On the first pass we simply search for the lowest page that
   1147   1.8  christos 	 we havn't relaxed yet. Note that the pass count is reset
   1148   1.8  christos 	 each time a page is complete in order to move on to the next page.
   1149   1.8  christos 	 If we can't find any more pages then we are finished.  */
   1150   1.1  christos       if (new_pass)
   1151   1.1  christos 	{
   1152   1.1  christos 	  pass = 1;
   1153  1.10  christos 	  new_pass = false;
   1154  1.10  christos 	  changed = true; /* Pre-initialize to break out of pass 1.  */
   1155   1.1  christos 	  search_addr = 0xFFFFFFFF;
   1156   1.1  christos 	}
   1157   1.1  christos 
   1158   1.1  christos       if ((BASEADDR (sec) + sec->size < search_addr)
   1159   1.1  christos 	  && (BASEADDR (sec) + sec->size > page_end))
   1160   1.1  christos 	{
   1161   1.1  christos 	  if (BASEADDR (sec) <= page_end)
   1162   1.1  christos 	    search_addr = page_end + 1;
   1163   1.1  christos 	  else
   1164   1.1  christos 	    search_addr = BASEADDR (sec);
   1165   1.1  christos 
   1166   1.1  christos 	  /* Found a page => more work to do.  */
   1167  1.10  christos 	  *again = true;
   1168   1.1  christos 	}
   1169   1.1  christos     }
   1170   1.1  christos   else
   1171   1.1  christos     {
   1172   1.1  christos       if (new_pass)
   1173   1.1  christos 	{
   1174  1.10  christos 	  new_pass = false;
   1175  1.10  christos 	  changed = false;
   1176   1.1  christos 	  page_start = PAGENO (search_addr);
   1177   1.1  christos 	  page_end = page_start | 0x00003FFF;
   1178   1.1  christos 	}
   1179   1.1  christos 
   1180   1.1  christos       /* Only process sections in range.  */
   1181   1.1  christos       if ((BASEADDR (sec) + sec->size >= page_start)
   1182   1.1  christos 	  && (BASEADDR (sec) <= page_end))
   1183   1.1  christos 	{
   1184   1.8  christos 	  if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end))
   1185  1.10  christos 	    return false;
   1186   1.1  christos 	}
   1187  1.10  christos       *again = true;
   1188   1.1  christos     }
   1189   1.1  christos 
   1190   1.1  christos   /* Perform some house keeping after relaxing the section.  */
   1191   1.1  christos 
   1192   1.1  christos   if (isymbuf != NULL
   1193   1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
   1194   1.1  christos     {
   1195   1.1  christos       if (! link_info->keep_memory)
   1196   1.1  christos 	free (isymbuf);
   1197   1.1  christos       else
   1198   1.1  christos 	symtab_hdr->contents = (unsigned char *) isymbuf;
   1199   1.1  christos     }
   1200   1.1  christos 
   1201   1.1  christos   if (contents != NULL
   1202   1.1  christos       && elf_section_data (sec)->this_hdr.contents != contents)
   1203   1.1  christos     {
   1204   1.1  christos       if (! link_info->keep_memory)
   1205   1.1  christos 	free (contents);
   1206   1.1  christos       else
   1207   1.1  christos 	{
   1208   1.1  christos 	  /* Cache the section contents for elf_link_input_bfd.  */
   1209   1.1  christos 	  elf_section_data (sec)->this_hdr.contents = contents;
   1210   1.1  christos 	}
   1211   1.1  christos     }
   1212   1.1  christos 
   1213   1.9  christos   if (elf_section_data (sec)->relocs != internal_relocs)
   1214   1.1  christos     free (internal_relocs);
   1215   1.1  christos 
   1216  1.10  christos   return true;
   1217   1.1  christos 
   1218   1.1  christos  error_return:
   1219   1.9  christos   if (symtab_hdr->contents != (unsigned char *) isymbuf)
   1220   1.1  christos     free (isymbuf);
   1221   1.9  christos   if (elf_section_data (sec)->this_hdr.contents != contents)
   1222   1.1  christos     free (contents);
   1223   1.9  christos   if (elf_section_data (sec)->relocs != internal_relocs)
   1224   1.1  christos     free (internal_relocs);
   1225  1.10  christos   return false;
   1226   1.1  christos }
   1227   1.1  christos 
   1228   1.1  christos /* Set the howto pointer for a IP2K ELF reloc.  */
   1229   1.1  christos 
   1230  1.10  christos static bool
   1231   1.8  christos ip2k_info_to_howto_rela (bfd * abfd,
   1232   1.1  christos 			 arelent * cache_ptr,
   1233   1.1  christos 			 Elf_Internal_Rela * dst)
   1234   1.1  christos {
   1235   1.1  christos   unsigned int r_type;
   1236   1.1  christos 
   1237   1.1  christos   r_type = ELF32_R_TYPE (dst->r_info);
   1238   1.3  christos   if (r_type >= (unsigned int) R_IP2K_max)
   1239   1.3  christos     {
   1240   1.7  christos       /* xgettext:c-format */
   1241   1.8  christos       _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
   1242   1.8  christos 			  abfd, r_type);
   1243   1.8  christos       bfd_set_error (bfd_error_bad_value);
   1244  1.10  christos       return false;
   1245   1.3  christos     }
   1246   1.1  christos   cache_ptr->howto = & ip2k_elf_howto_table [r_type];
   1247  1.10  christos   return true;
   1248   1.1  christos }
   1249   1.1  christos 
   1250   1.1  christos /* Perform a single relocation.
   1251   1.1  christos    By default we use the standard BFD routines.  */
   1252   1.1  christos 
   1253   1.1  christos static bfd_reloc_status_type
   1254   1.1  christos ip2k_final_link_relocate (reloc_howto_type *  howto,
   1255   1.8  christos 			  bfd *		      input_bfd,
   1256   1.8  christos 			  asection *	      input_section,
   1257   1.8  christos 			  bfd_byte *	      contents,
   1258   1.1  christos 			  Elf_Internal_Rela * rel,
   1259   1.8  christos 			  bfd_vma	      relocation)
   1260   1.1  christos {
   1261   1.1  christos   static bfd_vma page_addr = 0;
   1262   1.1  christos 
   1263   1.1  christos   bfd_reloc_status_type r = bfd_reloc_ok;
   1264   1.1  christos   switch (howto->type)
   1265   1.1  christos     {
   1266   1.1  christos       /* Handle data space relocations.  */
   1267   1.1  christos     case R_IP2K_FR9:
   1268   1.1  christos     case R_IP2K_BANK:
   1269   1.1  christos       if ((relocation & IP2K_DATA_MASK) == IP2K_DATA_VALUE)
   1270   1.1  christos 	relocation &= ~IP2K_DATA_MASK;
   1271   1.1  christos       else
   1272   1.1  christos 	r = bfd_reloc_notsupported;
   1273   1.1  christos       break;
   1274   1.1  christos 
   1275   1.1  christos     case R_IP2K_LO8DATA:
   1276   1.1  christos     case R_IP2K_HI8DATA:
   1277   1.1  christos     case R_IP2K_EX8DATA:
   1278   1.1  christos       break;
   1279   1.1  christos 
   1280   1.1  christos       /* Handle insn space relocations.  */
   1281   1.1  christos     case R_IP2K_PAGE3:
   1282   1.1  christos       page_addr = BASEADDR (input_section) + rel->r_offset;
   1283   1.1  christos       if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
   1284   1.1  christos 	relocation &= ~IP2K_INSN_MASK;
   1285   1.1  christos       else
   1286   1.1  christos 	r = bfd_reloc_notsupported;
   1287   1.1  christos       break;
   1288   1.1  christos 
   1289   1.1  christos     case R_IP2K_ADDR16CJP:
   1290   1.1  christos       if (BASEADDR (input_section) + rel->r_offset != page_addr + 2)
   1291   1.1  christos 	{
   1292   1.1  christos 	  /* No preceding page instruction, verify that it isn't needed.  */
   1293   1.1  christos 	  if (PAGENO (relocation + rel->r_addend) !=
   1294   1.1  christos 	      ip2k_nominal_page_bits (input_bfd, input_section,
   1295   1.8  christos 				      rel->r_offset, contents))
   1296   1.7  christos 	    /* xgettext:c-format */
   1297   1.8  christos 	    _bfd_error_handler
   1298   1.8  christos 	      (_("ip2k linker: missing page instruction "
   1299   1.8  christos 		 "at %#" PRIx64 " (dest = %#" PRIx64 ")"),
   1300   1.8  christos 	       (uint64_t) (BASEADDR (input_section) + rel->r_offset),
   1301   1.8  christos 	       (uint64_t) (relocation + rel->r_addend));
   1302   1.8  christos 	}
   1303   1.1  christos       else if (ip2k_relaxed)
   1304   1.8  christos 	{
   1305   1.8  christos 	  /* Preceding page instruction. Verify that the page instruction is
   1306   1.8  christos 	     really needed. One reason for the relaxation to miss a page is if
   1307   1.8  christos 	     the section is not marked as executable.  */
   1308   1.1  christos 	  if (!ip2k_is_switch_table_128 (input_bfd, input_section,
   1309   1.1  christos 					 rel->r_offset - 2, contents)
   1310   1.1  christos 	      && !ip2k_is_switch_table_256 (input_bfd, input_section,
   1311   1.1  christos 					    rel->r_offset - 2, contents)
   1312   1.1  christos 	      && (PAGENO (relocation + rel->r_addend) ==
   1313   1.1  christos 		  ip2k_nominal_page_bits (input_bfd, input_section,
   1314   1.1  christos 					  rel->r_offset - 2, contents)))
   1315   1.7  christos 	    /* xgettext:c-format */
   1316   1.8  christos 	    _bfd_error_handler
   1317   1.8  christos 	      (_("ip2k linker: redundant page instruction "
   1318   1.8  christos 		 "at %#" PRIx64 " (dest = %#" PRIx64 ")"),
   1319   1.8  christos 	       (uint64_t) page_addr,
   1320   1.8  christos 	       (uint64_t) (relocation + rel->r_addend));
   1321   1.8  christos 	}
   1322   1.1  christos       if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
   1323   1.1  christos 	relocation &= ~IP2K_INSN_MASK;
   1324   1.1  christos       else
   1325   1.1  christos 	r = bfd_reloc_notsupported;
   1326   1.1  christos       break;
   1327   1.1  christos 
   1328   1.1  christos     case R_IP2K_LO8INSN:
   1329   1.1  christos     case R_IP2K_HI8INSN:
   1330   1.1  christos     case R_IP2K_PC_SKIP:
   1331   1.1  christos       if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
   1332   1.1  christos 	relocation &= ~IP2K_INSN_MASK;
   1333   1.1  christos       else
   1334   1.1  christos 	r = bfd_reloc_notsupported;
   1335   1.1  christos       break;
   1336   1.1  christos 
   1337   1.1  christos     case R_IP2K_16:
   1338   1.1  christos       /* If this is a relocation involving a TEXT
   1339   1.1  christos 	 symbol, reduce it to a word address.  */
   1340   1.1  christos       if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
   1341   1.1  christos 	howto = &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
   1342   1.1  christos       break;
   1343   1.1  christos 
   1344   1.1  christos       /* Pass others through.  */
   1345   1.1  christos     default:
   1346   1.1  christos       break;
   1347   1.1  christos     }
   1348   1.1  christos 
   1349   1.1  christos   /* Only install relocation if above tests did not disqualify it.  */
   1350   1.1  christos   if (r == bfd_reloc_ok)
   1351   1.1  christos     r = _bfd_final_link_relocate (howto, input_bfd, input_section,
   1352   1.1  christos 				  contents, rel->r_offset,
   1353   1.1  christos 				  relocation, rel->r_addend);
   1354   1.1  christos 
   1355   1.1  christos   return r;
   1356   1.1  christos }
   1357   1.1  christos 
   1358   1.1  christos /* Relocate a IP2K ELF section.
   1359   1.1  christos 
   1360   1.1  christos    The RELOCATE_SECTION function is called by the new ELF backend linker
   1361   1.1  christos    to handle the relocations for a section.
   1362   1.1  christos 
   1363   1.1  christos    The relocs are always passed as Rela structures; if the section
   1364   1.1  christos    actually uses Rel structures, the r_addend field will always be
   1365   1.1  christos    zero.
   1366   1.1  christos 
   1367   1.1  christos    This function is responsible for adjusting the section contents as
   1368   1.1  christos    necessary, and (if using Rela relocs and generating a relocatable
   1369   1.1  christos    output file) adjusting the reloc addend as necessary.
   1370   1.1  christos 
   1371   1.1  christos    This function does not have to worry about setting the reloc
   1372   1.1  christos    address or the reloc symbol index.
   1373   1.1  christos 
   1374   1.1  christos    LOCAL_SYMS is a pointer to the swapped in local symbols.
   1375   1.1  christos 
   1376   1.1  christos    LOCAL_SECTIONS is an array giving the section in the input file
   1377   1.1  christos    corresponding to the st_shndx field of each local symbol.
   1378   1.1  christos 
   1379   1.1  christos    The global hash table entry for the global symbols can be found
   1380   1.1  christos    via elf_sym_hashes (input_bfd).
   1381   1.1  christos 
   1382   1.1  christos    When generating relocatable output, this function must handle
   1383   1.1  christos    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
   1384   1.1  christos    going to be the section symbol corresponding to the output
   1385   1.1  christos    section, which means that the addend must be adjusted
   1386   1.1  christos    accordingly.  */
   1387   1.1  christos 
   1388  1.10  christos static int
   1389   1.1  christos ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
   1390   1.1  christos 			   struct bfd_link_info *info,
   1391   1.1  christos 			   bfd *input_bfd,
   1392   1.1  christos 			   asection *input_section,
   1393   1.1  christos 			   bfd_byte *contents,
   1394   1.1  christos 			   Elf_Internal_Rela *relocs,
   1395   1.1  christos 			   Elf_Internal_Sym *local_syms,
   1396   1.1  christos 			   asection **local_sections)
   1397   1.1  christos {
   1398   1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1399   1.1  christos   struct elf_link_hash_entry **sym_hashes;
   1400   1.1  christos   Elf_Internal_Rela *rel;
   1401   1.1  christos   Elf_Internal_Rela *relend;
   1402   1.1  christos 
   1403   1.1  christos   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   1404   1.1  christos   sym_hashes = elf_sym_hashes (input_bfd);
   1405   1.1  christos   relend     = relocs + input_section->reloc_count;
   1406   1.1  christos 
   1407   1.1  christos   for (rel = relocs; rel < relend; rel ++)
   1408   1.1  christos     {
   1409   1.8  christos       reloc_howto_type *	   howto;
   1410   1.8  christos       unsigned long		   r_symndx;
   1411   1.8  christos       Elf_Internal_Sym *	   sym;
   1412   1.8  christos       asection *		   sec;
   1413   1.1  christos       struct elf_link_hash_entry * h;
   1414   1.8  christos       bfd_vma			   relocation;
   1415   1.8  christos       bfd_reloc_status_type	   r;
   1416   1.8  christos       const char *		   name = NULL;
   1417   1.8  christos       int			   r_type;
   1418   1.1  christos 
   1419   1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
   1420   1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   1421   1.1  christos       howto  = ip2k_elf_howto_table + r_type;
   1422   1.1  christos       h      = NULL;
   1423   1.1  christos       sym    = NULL;
   1424   1.1  christos       sec    = NULL;
   1425   1.1  christos 
   1426   1.1  christos       if (r_symndx < symtab_hdr->sh_info)
   1427   1.1  christos 	{
   1428   1.1  christos 	  sym = local_syms + r_symndx;
   1429   1.1  christos 	  sec = local_sections [r_symndx];
   1430   1.1  christos 	  relocation = BASEADDR (sec) + sym->st_value;
   1431   1.1  christos 
   1432   1.1  christos 	  name = bfd_elf_string_from_elf_section
   1433   1.1  christos 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
   1434   1.9  christos 	  name = name == NULL ? bfd_section_name (sec) : name;
   1435   1.1  christos 	}
   1436   1.1  christos       else
   1437   1.1  christos 	{
   1438  1.10  christos 	  bool warned, ignored;
   1439  1.10  christos 	  bool unresolved_reloc;
   1440   1.1  christos 
   1441   1.1  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   1442   1.1  christos 				   r_symndx, symtab_hdr, sym_hashes,
   1443   1.1  christos 				   h, sec, relocation,
   1444   1.1  christos 				   unresolved_reloc, warned, ignored);
   1445   1.1  christos 
   1446   1.1  christos 	  name = h->root.root.string;
   1447   1.1  christos 	}
   1448   1.1  christos 
   1449   1.1  christos       if (sec != NULL && discarded_section (sec))
   1450   1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
   1451   1.1  christos 					 rel, 1, relend, howto, 0, contents);
   1452   1.1  christos 
   1453   1.6  christos       if (bfd_link_relocatable (info))
   1454   1.1  christos 	continue;
   1455   1.1  christos 
   1456   1.1  christos       /* Finally, the sole IP2K-specific part.  */
   1457   1.1  christos       r = ip2k_final_link_relocate (howto, input_bfd, input_section,
   1458   1.1  christos 				     contents, rel, relocation);
   1459   1.1  christos 
   1460   1.1  christos       if (r != bfd_reloc_ok)
   1461   1.1  christos 	{
   1462   1.1  christos 	  const char * msg = NULL;
   1463   1.1  christos 
   1464   1.1  christos 	  switch (r)
   1465   1.1  christos 	    {
   1466   1.1  christos 	    case bfd_reloc_overflow:
   1467   1.6  christos 	      (*info->callbacks->reloc_overflow)
   1468   1.1  christos 		(info, (h ? &h->root : NULL), name, howto->name,
   1469   1.1  christos 		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
   1470   1.1  christos 	      break;
   1471   1.1  christos 
   1472   1.1  christos 	    case bfd_reloc_undefined:
   1473   1.6  christos 	      (*info->callbacks->undefined_symbol)
   1474  1.10  christos 		(info, name, input_bfd, input_section, rel->r_offset, true);
   1475   1.1  christos 	      break;
   1476   1.1  christos 
   1477   1.1  christos 	    case bfd_reloc_outofrange:
   1478   1.1  christos 	      msg = _("internal error: out of range error");
   1479   1.1  christos 	      break;
   1480   1.1  christos 
   1481   1.1  christos 	      /* This is how ip2k_final_link_relocate tells us of a non-kosher
   1482   1.8  christos 		 reference between insn & data address spaces.  */
   1483   1.1  christos 	    case bfd_reloc_notsupported:
   1484   1.8  christos 	      if (sym != NULL) /* Only if it's not an unresolved symbol.  */
   1485   1.8  christos 		 msg = _("unsupported relocation between data/insn address spaces");
   1486   1.1  christos 	      break;
   1487   1.1  christos 
   1488   1.1  christos 	    case bfd_reloc_dangerous:
   1489   1.1  christos 	      msg = _("internal error: dangerous relocation");
   1490   1.1  christos 	      break;
   1491   1.1  christos 
   1492   1.1  christos 	    default:
   1493   1.1  christos 	      msg = _("internal error: unknown error");
   1494   1.1  christos 	      break;
   1495   1.1  christos 	    }
   1496   1.1  christos 
   1497   1.1  christos 	  if (msg)
   1498   1.6  christos 	    (*info->callbacks->warning) (info, msg, name, input_bfd,
   1499   1.6  christos 					 input_section, rel->r_offset);
   1500   1.1  christos 	}
   1501   1.1  christos     }
   1502   1.1  christos 
   1503  1.10  christos   return true;
   1504   1.1  christos }
   1505   1.1  christos 
   1506   1.3  christos #define TARGET_BIG_SYM	 ip2k_elf32_vec
   1507   1.1  christos #define TARGET_BIG_NAME  "elf32-ip2k"
   1508   1.1  christos 
   1509   1.1  christos #define ELF_ARCH	 bfd_arch_ip2k
   1510   1.1  christos #define ELF_MACHINE_CODE EM_IP2K
   1511   1.1  christos #define ELF_MACHINE_ALT1 EM_IP2K_OLD
   1512   1.1  christos #define ELF_MAXPAGESIZE  1 /* No pages on the IP2K.  */
   1513   1.1  christos 
   1514   1.1  christos #define elf_info_to_howto_rel			NULL
   1515   1.1  christos #define elf_info_to_howto			ip2k_info_to_howto_rela
   1516   1.1  christos 
   1517   1.8  christos #define elf_backend_can_gc_sections		1
   1518   1.1  christos #define elf_backend_rela_normal			1
   1519   1.1  christos #define elf_backend_relocate_section		ip2k_elf_relocate_section
   1520   1.1  christos 
   1521   1.1  christos #define elf_symbol_leading_char			'_'
   1522   1.1  christos #define bfd_elf32_bfd_reloc_type_lookup		ip2k_reloc_type_lookup
   1523   1.1  christos #define bfd_elf32_bfd_reloc_name_lookup	ip2k_reloc_name_lookup
   1524   1.1  christos #define bfd_elf32_bfd_relax_section		ip2k_elf_relax_section
   1525   1.1  christos 
   1526   1.1  christos #include "elf32-target.h"
   1527