Home | History | Annotate | Line # | Download | only in bfd
elf32-ip2k.c revision 1.7
      1  1.1  christos /* Ubicom IP2xxx specific support for 32-bit ELF
      2  1.7  christos    Copyright (C) 2000-2017 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.1  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.1  christos static bfd_boolean 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.1  christos     HOWTO(t,                    /* type */ \
    130  1.1  christos           rs,                   /* rightshift */ \
    131  1.1  christos           s,                    /* size (0 = byte, 1 = short, 2 = long) */ \
    132  1.1  christos           bs,                   /* bitsize */ \
    133  1.1  christos           pr,                   /* pc_relative */ \
    134  1.1  christos           bp,                   /* bitpos */ \
    135  1.1  christos           complain_overflow_dont,/* complain_on_overflow */ \
    136  1.1  christos           bfd_elf_generic_reloc,/* special_function */ \
    137  1.1  christos           name,                 /* name */ \
    138  1.1  christos           FALSE,                /* partial_inplace */ \
    139  1.1  christos           sm,                   /* src_mask */ \
    140  1.1  christos           dm,                   /* dst_mask */ \
    141  1.1  christos           pr)                   /* pcrel_offset */
    142  1.1  christos 
    143  1.1  christos   /* This reloc does nothing.  */
    144  1.5  christos   IP2K_HOWTO (R_IP2K_NONE, 0,3,0, FALSE, 0, "R_IP2K_NONE", 0, 0),
    145  1.1  christos   /* A 16 bit absolute relocation.  */
    146  1.1  christos   IP2K_HOWTO (R_IP2K_16, 0,1,16, FALSE, 0, "R_IP2K_16", 0, 0xffff),
    147  1.1  christos   /* A 32 bit absolute relocation.  */
    148  1.1  christos   IP2K_HOWTO (R_IP2K_32, 0,2,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.1  christos   IP2K_HOWTO (R_IP2K_FR9, 0,1,9, FALSE, 0, "R_IP2K_FR9", 0, 0x00ff),
    151  1.1  christos   /* A 4-bit data relocation.  */
    152  1.1  christos   IP2K_HOWTO (R_IP2K_BANK, 8,1,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.1  christos   IP2K_HOWTO (R_IP2K_ADDR16CJP, 1,1,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.1  christos   IP2K_HOWTO (R_IP2K_PAGE3, 14,1,3, FALSE, 0, "R_IP2K_PAGE3", 0, 0x0007),
    157  1.1  christos   /* Two 8-bit data relocations.  */
    158  1.1  christos   IP2K_HOWTO (R_IP2K_LO8DATA, 0,1,8, FALSE, 0, "R_IP2K_LO8DATA", 0, 0x00ff),
    159  1.1  christos   IP2K_HOWTO (R_IP2K_HI8DATA, 8,1,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.1  christos   IP2K_HOWTO (R_IP2K_LO8INSN, 1,1,8, FALSE, 0, "R_IP2K_LO8INSN", 0, 0x00ff),
    162  1.1  christos   IP2K_HOWTO (R_IP2K_HI8INSN, 9,1,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.1  christos   IP2K_HOWTO (R_IP2K_PC_SKIP, 1,1,1, FALSE, 12, "R_IP2K_PC_SKIP", 0xfffe, 0x1000),
    166  1.1  christos   /* 16 bit word address.  */
    167  1.1  christos   IP2K_HOWTO (R_IP2K_TEXT, 1,1,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.1  christos   IP2K_HOWTO (R_IP2K_FR_OFFSET, 0,1,9, FALSE, 0, "R_IP2K_FR_OFFSET", 0x180, 0x007f),
    170  1.1  christos   /* Bits 23:16 of an address.  */
    171  1.1  christos   IP2K_HOWTO (R_IP2K_EX8DATA, 16,1,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.1  christos static bfd_boolean
    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.1  christos 	return TRUE;
    259  1.1  christos 
    260  1.1  christos       opcodes ++;
    261  1.1  christos     }
    262  1.1  christos 
    263  1.1  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.1  christos           sc
    318  1.1  christos           page    $nnn0
    319  1.1  christos           jmp     $nnn0
    320  1.1  christos           add     w,wreg
    321  1.1  christos           add     pcl,w
    322  1.1  christos   addr=>
    323  1.1  christos           page    $nnn1
    324  1.1  christos           jmp     $nnn1
    325  1.1  christos  	   page    $nnn2
    326  1.1  christos  	   jmp     $nnn2
    327  1.1  christos  	   ...
    328  1.1  christos  	   page    $nnnN
    329  1.1  christos  	   jmp     $nnnN
    330  1.1  christos 
    331  1.1  christos   After relaxation.
    332  1.1  christos   	   sc
    333  1.1  christos  	   page    $nnn0
    334  1.1  christos   	   jmp     $nnn0
    335  1.1  christos  	   add     pcl,w
    336  1.1  christos   addr=>
    337  1.1  christos   	   jmp     $nnn1
    338  1.1  christos  	   jmp     $nnn2
    339  1.1  christos  	   ...
    340  1.1  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.1  christos           push    %lo8insn(label) ; Push address of table
    388  1.1  christos           push    %hi8insn(label)
    389  1.1  christos           add     w,wreg          ; index*2 => offset
    390  1.1  christos           snc                     ; CARRY SET?
    391  1.1  christos           inc     1(sp)           ; Propagate MSB into table address
    392  1.1  christos           add     2(sp),w         ; Add low bits of offset to table address
    393  1.1  christos           snc                     ; and handle any carry-out
    394  1.1  christos           inc     1(sp)
    395  1.1  christos    addr=>
    396  1.1  christos           page    __indjmp        ; Do an indirect jump to that location
    397  1.1  christos           jmp     __indjmp
    398  1.1  christos    label:                         ; case dispatch table starts here
    399  1.1  christos  	   page    $nnn1
    400  1.1  christos  	   jmp	   $nnn1
    401  1.1  christos  	   page	   $nnn2
    402  1.1  christos  	   jmp     $nnn2
    403  1.1  christos  	   ...
    404  1.1  christos  	   page    $nnnN
    405  1.1  christos  	   jmp	   $nnnN
    406  1.1  christos 
    407  1.1  christos   After relaxation.
    408  1.1  christos           push    %lo8insn(label) ; Push address of table
    409  1.1  christos           push    %hi8insn(label)
    410  1.1  christos           add     2(sp),w         ; Add low bits of offset to table address
    411  1.1  christos           snc                     ; and handle any carry-out
    412  1.1  christos           inc     1(sp)
    413  1.1  christos   addr=>
    414  1.1  christos           page    __indjmp        ; Do an indirect jump to that location
    415  1.1  christos           jmp     __indjmp
    416  1.1  christos    label:                         ; case dispatch table starts here
    417  1.1  christos           jmp     $nnn1
    418  1.1  christos           jmp     $nnn2
    419  1.1  christos           ...
    420  1.1  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.1  christos         {
    519  1.1  christos 	  ip2k_get_mem (abfd, contents + addr - 2, 2, code);
    520  1.1  christos           if (IS_SKIP_OPCODE (code))
    521  1.1  christos 	    /* Page is conditional.  */
    522  1.1  christos 	    continue;
    523  1.1  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.1  christos static bfd_boolean
    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.1  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.1  christos     return FALSE;
    553  1.1  christos 
    554  1.1  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.1  christos         {
    597  1.1  christos           /* Get the value of the symbol referred to by the reloc.  */
    598  1.1  christos           if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    599  1.1  christos             {
    600  1.1  christos               asection *sym_sec;
    601  1.1  christos 
    602  1.1  christos               /* A local symbol.  */
    603  1.1  christos 	      isym = isymbuf + ELF32_R_SYM (irel->r_info);
    604  1.1  christos               sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
    605  1.1  christos 
    606  1.1  christos               if (isym->st_shndx == shndx)
    607  1.1  christos                 {
    608  1.1  christos                   bfd_vma baseaddr = BASEADDR (sec);
    609  1.1  christos                   bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
    610  1.1  christos                                    + irel->r_addend;
    611  1.1  christos 
    612  1.1  christos                   if ((baseaddr + addr + noadj) <= symval
    613  1.1  christos                       && symval < (baseaddr + endaddr))
    614  1.1  christos                     irel->r_addend += count;
    615  1.1  christos                 }
    616  1.1  christos             }
    617  1.1  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.1  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.1  christos   if (stab)
    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.1  christos 	      if (stabcontents != NULL)
    642  1.1  christos 		free (stabcontents);
    643  1.1  christos 	      return;
    644  1.1  christos 	    }
    645  1.1  christos 
    646  1.1  christos 	  /* We need to remember this.  */
    647  1.1  christos 	  elf_section_data (stab)->this_hdr.contents = stabcontents;
    648  1.1  christos 	}
    649  1.1  christos 
    650  1.1  christos       stabend = stabcontents + stab_size;
    651  1.1  christos 
    652  1.1  christos       for (irel = irelbase; irel < irelend; irel++)
    653  1.1  christos 	{
    654  1.1  christos 	  if (ELF32_R_TYPE (irel->r_info) != R_IP2K_NONE)
    655  1.1  christos 	    {
    656  1.1  christos 	      /* Get the value of the symbol referred to by the reloc.  */
    657  1.1  christos 	      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
    658  1.1  christos 		{
    659  1.1  christos 		  asection *sym_sec;
    660  1.1  christos 
    661  1.1  christos 		  /* A local symbol.  */
    662  1.1  christos 		  isym = isymbuf + ELF32_R_SYM (irel->r_info);
    663  1.1  christos 		  sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
    664  1.1  christos 
    665  1.1  christos 		  if (sym_sec == sec)
    666  1.1  christos 		    {
    667  1.1  christos 		      const char *name;
    668  1.1  christos 		      unsigned char type;
    669  1.1  christos 		      bfd_vma value;
    670  1.1  christos 		      bfd_vma baseaddr = BASEADDR (sec);
    671  1.1  christos 		      bfd_vma symval = BASEADDR (sym_sec) + isym->st_value
    672  1.1  christos 			+ irel->r_addend;
    673  1.1  christos 
    674  1.1  christos 		      if ((baseaddr + addr) <= symval
    675  1.1  christos 			  && symval <= (baseaddr + endaddr))
    676  1.1  christos 			irel->r_addend += count;
    677  1.1  christos 
    678  1.1  christos 		      /* Go hunt up a function and fix its line info if needed.  */
    679  1.1  christos 		      stabp = stabcontents + irel->r_offset - 8;
    680  1.1  christos 
    681  1.1  christos 		      /* Go pullout the stab entry.  */
    682  1.1  christos 		      type  = bfd_h_get_8 (abfd, stabp + TYPEOFF);
    683  1.1  christos 		      value = bfd_h_get_32 (abfd, stabp + VALOFF);
    684  1.1  christos 
    685  1.1  christos 		      name = bfd_get_stab_name (type);
    686  1.1  christos 
    687  1.1  christos 		      if (strcmp (name, "FUN") == 0)
    688  1.1  christos 			{
    689  1.1  christos 			  int function_adjusted = 0;
    690  1.1  christos 
    691  1.1  christos 			  if (symval > (baseaddr + addr))
    692  1.1  christos 			    /* Not in this function.  */
    693  1.1  christos 			    continue;
    694  1.1  christos 
    695  1.1  christos 			  /* Hey we got a function hit.  */
    696  1.1  christos 			  stabp += STABSIZE;
    697  1.1  christos 			  for (;stabp < stabend; stabp += STABSIZE)
    698  1.1  christos 			    {
    699  1.1  christos 			      /* Go pullout the stab entry.  */
    700  1.1  christos 			      type  = bfd_h_get_8 (abfd, stabp + TYPEOFF);
    701  1.1  christos 			      value = bfd_h_get_32 (abfd, stabp + VALOFF);
    702  1.1  christos 
    703  1.1  christos 			      name = bfd_get_stab_name (type);
    704  1.1  christos 
    705  1.1  christos 			      if (strcmp (name, "FUN") == 0)
    706  1.1  christos 				{
    707  1.1  christos 				  /* Hit another function entry.  */
    708  1.1  christos 				  if (function_adjusted)
    709  1.1  christos 				    {
    710  1.1  christos 				      /* Adjust the value.  */
    711  1.1  christos 				      value += count;
    712  1.1  christos 
    713  1.1  christos 				      /* We need to put it back.  */
    714  1.1  christos 				      bfd_h_put_32 (abfd, value,stabp + VALOFF);
    715  1.1  christos 				    }
    716  1.1  christos 
    717  1.1  christos 				  /* And then bale out.  */
    718  1.1  christos 				  break;
    719  1.1  christos 				}
    720  1.1  christos 
    721  1.1  christos 			      if (strcmp (name, "SLINE") == 0)
    722  1.1  christos 				{
    723  1.1  christos 				  /* Got a line entry.  */
    724  1.1  christos 				  if ((baseaddr + addr) <= (symval + value))
    725  1.1  christos 				    {
    726  1.1  christos 				      /* Adjust the line entry.  */
    727  1.1  christos 				      value += count;
    728  1.1  christos 
    729  1.1  christos 				      /* We need to put it back.  */
    730  1.1  christos 				      bfd_h_put_32 (abfd, value,stabp + VALOFF);
    731  1.1  christos 				      function_adjusted = 1;
    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 
    742  1.1  christos   /* When adding an instruction back it is sometimes necessary to move any
    743  1.1  christos      global or local symbol that was referencing the first instruction of
    744  1.1  christos      the moved block to refer to the first instruction of the inserted block.
    745  1.1  christos 
    746  1.1  christos      For example adding a PAGE instruction before a CALL or JMP requires
    747  1.1  christos      that any label on the CALL or JMP is moved to the PAGE insn.  */
    748  1.1  christos   addr += noadj;
    749  1.1  christos 
    750  1.1  christos   /* Adjust the local symbols defined in this section.  */
    751  1.1  christos   isymend = isymbuf + symtab_hdr->sh_info;
    752  1.1  christos   for (isym = isymbuf; isym < isymend; isym++)
    753  1.1  christos     {
    754  1.1  christos       if (isym->st_shndx == shndx
    755  1.1  christos 	  && addr <= isym->st_value
    756  1.1  christos 	  && isym->st_value < endaddr)
    757  1.1  christos 	isym->st_value += count;
    758  1.1  christos     }
    759  1.1  christos 
    760  1.1  christos   /* Now adjust the global symbols defined in this section.  */
    761  1.1  christos   symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)
    762  1.1  christos 	      - symtab_hdr->sh_info);
    763  1.1  christos   sym_hashes = elf_sym_hashes (abfd);
    764  1.1  christos   end_hashes = sym_hashes + symcount;
    765  1.1  christos   for (; sym_hashes < end_hashes; sym_hashes++)
    766  1.1  christos     {
    767  1.1  christos       struct elf_link_hash_entry *sym_hash = *sym_hashes;
    768  1.1  christos 
    769  1.1  christos       if ((sym_hash->root.type == bfd_link_hash_defined
    770  1.1  christos 	   || sym_hash->root.type == bfd_link_hash_defweak)
    771  1.1  christos 	  && sym_hash->root.u.def.section == sec)
    772  1.1  christos 	{
    773  1.1  christos           if (addr <= sym_hash->root.u.def.value
    774  1.1  christos               && sym_hash->root.u.def.value < endaddr)
    775  1.1  christos 	    sym_hash->root.u.def.value += count;
    776  1.1  christos 	}
    777  1.1  christos     }
    778  1.1  christos 
    779  1.1  christos   return;
    780  1.1  christos }
    781  1.1  christos 
    782  1.1  christos /* Delete some bytes from a section while relaxing.  */
    783  1.1  christos 
    784  1.1  christos static bfd_boolean
    785  1.1  christos ip2k_elf_relax_delete_bytes (bfd *abfd,
    786  1.1  christos 			     asection *sec,
    787  1.1  christos 			     bfd_vma addr,
    788  1.1  christos 			     int count)
    789  1.1  christos {
    790  1.1  christos   bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
    791  1.1  christos   bfd_vma endaddr = sec->size;
    792  1.1  christos 
    793  1.1  christos   /* Actually delete the bytes.  */
    794  1.1  christos   memmove (contents + addr, contents + addr + count,
    795  1.1  christos 	   endaddr - addr - count);
    796  1.1  christos 
    797  1.1  christos   sec->size -= count;
    798  1.1  christos 
    799  1.1  christos   adjust_all_relocations (abfd, sec, addr + count, endaddr, -count, 0);
    800  1.1  christos   return TRUE;
    801  1.1  christos }
    802  1.1  christos 
    803  1.1  christos static bfd_boolean
    804  1.1  christos ip2k_delete_page_insn (bfd *abfd ATTRIBUTE_UNUSED,
    805  1.1  christos 		       asection *sec,
    806  1.1  christos 		       Elf_Internal_Rela *irel,
    807  1.1  christos 		       bfd_boolean *again,
    808  1.1  christos 		       struct misc *misc)
    809  1.1  christos {
    810  1.1  christos   /* Note that we've changed the relocs, section contents, etc.  */
    811  1.1  christos   elf_section_data (sec)->relocs = misc->irelbase;
    812  1.1  christos   elf_section_data (sec)->this_hdr.contents = misc->contents;
    813  1.1  christos   misc->symtab_hdr->contents = (bfd_byte *) misc->isymbuf;
    814  1.1  christos 
    815  1.1  christos   /* Fix the relocation's type.  */
    816  1.1  christos   irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info), R_IP2K_NONE);
    817  1.1  christos 
    818  1.1  christos   /* Delete the PAGE insn.  */
    819  1.1  christos   if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset, 2))
    820  1.1  christos     return FALSE;
    821  1.1  christos 
    822  1.1  christos   /* Modified => will need to iterate relaxation again.  */
    823  1.1  christos   *again = TRUE;
    824  1.1  christos 
    825  1.1  christos   return TRUE;
    826  1.1  christos }
    827  1.1  christos 
    828  1.1  christos static bfd_boolean
    829  1.1  christos ip2k_relax_switch_table_128 (bfd *abfd ATTRIBUTE_UNUSED,
    830  1.1  christos 			     asection *sec,
    831  1.1  christos 			     Elf_Internal_Rela *irel,
    832  1.1  christos 			     bfd_boolean *again,
    833  1.1  christos 			     struct misc *misc)
    834  1.1  christos {
    835  1.1  christos   Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
    836  1.1  christos   Elf_Internal_Rela *ireltest = irel;
    837  1.1  christos   bfd_byte code[4];
    838  1.1  christos   bfd_vma addr;
    839  1.1  christos 
    840  1.1  christos   /* Test all page instructions.  */
    841  1.1  christos   addr = irel->r_offset;
    842  1.1  christos   while (1)
    843  1.1  christos     {
    844  1.1  christos       if (addr + 4 > sec->size)
    845  1.1  christos 	break;
    846  1.1  christos 
    847  1.1  christos       ip2k_get_mem (abfd, misc->contents + addr, 4, code);
    848  1.1  christos       if ((! IS_PAGE_OPCODE (code + 0))
    849  1.1  christos 	  || (! IS_JMP_OPCODE (code + 2)))
    850  1.1  christos 	break;
    851  1.1  christos 
    852  1.1  christos       /* Validate relocation entry (every entry should have a matching
    853  1.1  christos           relocation entry).  */
    854  1.1  christos       if (ireltest >= irelend)
    855  1.1  christos         {
    856  1.1  christos 	  _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
    857  1.1  christos           return FALSE;
    858  1.1  christos         }
    859  1.1  christos 
    860  1.1  christos       if (ireltest->r_offset != addr)
    861  1.1  christos         {
    862  1.1  christos 	  _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
    863  1.1  christos           return FALSE;
    864  1.1  christos         }
    865  1.1  christos 
    866  1.1  christos       if (! ip2k_test_page_insn (abfd, sec, ireltest, misc))
    867  1.1  christos 	/* Un-removable page insn => nothing can be done.  */
    868  1.1  christos 	return TRUE;
    869  1.1  christos 
    870  1.1  christos       addr += 4;
    871  1.1  christos       ireltest += 2;
    872  1.1  christos     }
    873  1.1  christos 
    874  1.1  christos   /* Relaxable. Adjust table header.  */
    875  1.1  christos   ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 4, code);
    876  1.1  christos   if ((! IS_ADD_W_WREG_OPCODE (code + 0))
    877  1.1  christos       || (! IS_ADD_PCL_W_OPCODE (code + 2)))
    878  1.1  christos     {
    879  1.1  christos       _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
    880  1.1  christos       return FALSE;
    881  1.1  christos     }
    882  1.1  christos 
    883  1.1  christos   if (!ip2k_elf_relax_delete_bytes (abfd, sec, irel->r_offset - 4, 2))
    884  1.1  christos     return FALSE;
    885  1.1  christos 
    886  1.1  christos   *again = TRUE;
    887  1.1  christos 
    888  1.1  christos   /* Delete all page instructions in table.  */
    889  1.1  christos   while (irel < ireltest)
    890  1.1  christos     {
    891  1.1  christos       if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
    892  1.1  christos 	return FALSE;
    893  1.1  christos       irel += 2;
    894  1.1  christos     }
    895  1.1  christos 
    896  1.1  christos   return TRUE;
    897  1.1  christos }
    898  1.1  christos 
    899  1.1  christos static bfd_boolean
    900  1.1  christos ip2k_relax_switch_table_256 (bfd *abfd ATTRIBUTE_UNUSED,
    901  1.1  christos 			     asection *sec,
    902  1.1  christos 			     Elf_Internal_Rela *irel,
    903  1.1  christos 			     bfd_boolean *again,
    904  1.1  christos 			     struct misc *misc)
    905  1.1  christos {
    906  1.1  christos   Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
    907  1.1  christos   Elf_Internal_Rela *ireltest = irel;
    908  1.1  christos   bfd_byte code[12];
    909  1.1  christos   bfd_vma addr;
    910  1.1  christos 
    911  1.1  christos   /* Test all page instructions.  */
    912  1.1  christos   addr = irel->r_offset;
    913  1.1  christos 
    914  1.1  christos   while (1)
    915  1.1  christos     {
    916  1.1  christos       if (addr + 4 > sec->size)
    917  1.1  christos 	break;
    918  1.1  christos 
    919  1.1  christos       ip2k_get_mem (abfd, misc->contents + addr, 4, code);
    920  1.1  christos 
    921  1.1  christos       if ((! IS_PAGE_OPCODE (code + 0))
    922  1.1  christos 	  || (! IS_JMP_OPCODE (code + 2)))
    923  1.1  christos 	break;
    924  1.1  christos 
    925  1.1  christos       /* Validate relocation entry (every entry should have a matching
    926  1.1  christos           relocation entry).  */
    927  1.1  christos       if (ireltest >= irelend)
    928  1.1  christos         {
    929  1.1  christos           _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
    930  1.1  christos           return FALSE;
    931  1.1  christos         }
    932  1.1  christos 
    933  1.1  christos       if (ireltest->r_offset != addr)
    934  1.1  christos         {
    935  1.1  christos           _bfd_error_handler (_("ip2k relaxer: switch table without complete matching relocation information."));
    936  1.1  christos           return FALSE;
    937  1.1  christos         }
    938  1.1  christos 
    939  1.1  christos       if (!ip2k_test_page_insn (abfd, sec, ireltest, misc))
    940  1.1  christos 	/* Un-removable page insn => nothing can be done.  */
    941  1.1  christos 	return TRUE;
    942  1.1  christos 
    943  1.1  christos       addr += 4;
    944  1.1  christos       ireltest += 2;
    945  1.1  christos     }
    946  1.1  christos 
    947  1.1  christos   /* Relaxable. Adjust table header.  */
    948  1.1  christos   ip2k_get_mem (abfd, misc->contents + irel->r_offset - 4, 2, code);
    949  1.1  christos   if (IS_PAGE_OPCODE (code))
    950  1.1  christos     addr = irel->r_offset - 16;
    951  1.1  christos   else
    952  1.1  christos     addr = irel->r_offset - 14;
    953  1.1  christos 
    954  1.1  christos   ip2k_get_mem (abfd, misc->contents + addr, 12, code);
    955  1.1  christos   if ((!IS_ADD_W_WREG_OPCODE (code + 0))
    956  1.1  christos       || (!IS_SNC_OPCODE (code + 2))
    957  1.1  christos       || (!IS_INC_1SP_OPCODE (code + 4))
    958  1.1  christos       || (!IS_ADD_2SP_W_OPCODE (code + 6))
    959  1.1  christos       || (!IS_SNC_OPCODE (code + 8))
    960  1.1  christos       || (!IS_INC_1SP_OPCODE (code + 10)))
    961  1.1  christos     {
    962  1.1  christos       _bfd_error_handler (_("ip2k relaxer: switch table header corrupt."));
    963  1.1  christos       return FALSE;
    964  1.1  christos     }
    965  1.1  christos 
    966  1.1  christos   /* Delete first 3 opcodes.  */
    967  1.1  christos   if (!ip2k_elf_relax_delete_bytes (abfd, sec, addr + 0, 6))
    968  1.1  christos     return FALSE;
    969  1.1  christos 
    970  1.1  christos   *again = TRUE;
    971  1.1  christos 
    972  1.1  christos   /* Delete all page instructions in table.  */
    973  1.1  christos   while (irel < ireltest)
    974  1.1  christos     {
    975  1.1  christos       if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
    976  1.1  christos 	return FALSE;
    977  1.1  christos       irel += 2;
    978  1.1  christos     }
    979  1.1  christos 
    980  1.1  christos   return TRUE;
    981  1.1  christos }
    982  1.1  christos 
    983  1.1  christos /* This function handles relaxation of a section in a specific page.  */
    984  1.1  christos 
    985  1.1  christos static bfd_boolean
    986  1.1  christos ip2k_elf_relax_section_page (bfd *abfd,
    987  1.1  christos 			     asection *sec,
    988  1.1  christos 			     bfd_boolean *again,
    989  1.1  christos 			     struct misc *misc,
    990  1.1  christos 			     unsigned long page_start,
    991  1.1  christos 			     unsigned long page_end)
    992  1.1  christos {
    993  1.1  christos   Elf_Internal_Rela *irelend = misc->irelbase + sec->reloc_count;
    994  1.1  christos   Elf_Internal_Rela *irel;
    995  1.1  christos   int switch_table_128;
    996  1.1  christos   int switch_table_256;
    997  1.1  christos 
    998  1.1  christos   /* Walk thru the section looking for relaxation opportunities.  */
    999  1.1  christos   for (irel = misc->irelbase; irel < irelend; irel++)
   1000  1.1  christos     {
   1001  1.1  christos       if (ELF32_R_TYPE (irel->r_info) != (int) R_IP2K_PAGE3)
   1002  1.1  christos 	/* Ignore non page instructions.  */
   1003  1.1  christos 	continue;
   1004  1.1  christos 
   1005  1.1  christos       if (BASEADDR (sec) + irel->r_offset < page_start)
   1006  1.1  christos 	/* Ignore page instructions on earlier page - they have
   1007  1.1  christos 	   already been processed. Remember that there is code flow
   1008  1.1  christos 	   that crosses a page boundary.  */
   1009  1.1  christos 	continue;
   1010  1.1  christos 
   1011  1.1  christos       if (BASEADDR (sec) + irel->r_offset > page_end)
   1012  1.1  christos 	/* Flow beyond end of page => nothing more to do for this page.  */
   1013  1.1  christos 	return TRUE;
   1014  1.1  christos 
   1015  1.1  christos       /* Detect switch tables.  */
   1016  1.1  christos       switch_table_128 = ip2k_is_switch_table_128 (abfd, sec, irel->r_offset, misc->contents);
   1017  1.1  christos       switch_table_256 = ip2k_is_switch_table_256 (abfd, sec, irel->r_offset, misc->contents);
   1018  1.1  christos 
   1019  1.1  christos       if ((switch_table_128 > 0) || (switch_table_256 > 0))
   1020  1.1  christos 	/* If the index is greater than 0 then it has already been processed.  */
   1021  1.1  christos 	continue;
   1022  1.1  christos 
   1023  1.1  christos       if (switch_table_128 == 0)
   1024  1.1  christos 	{
   1025  1.1  christos 	  if (!ip2k_relax_switch_table_128 (abfd, sec, irel, again, misc))
   1026  1.1  christos 	    return FALSE;
   1027  1.1  christos 
   1028  1.1  christos 	  continue;
   1029  1.1  christos 	}
   1030  1.1  christos 
   1031  1.1  christos       if (switch_table_256 == 0)
   1032  1.1  christos 	{
   1033  1.1  christos 	  if (!ip2k_relax_switch_table_256 (abfd, sec, irel, again, misc))
   1034  1.1  christos 	    return FALSE;
   1035  1.1  christos 
   1036  1.1  christos 	  continue;
   1037  1.1  christos 	}
   1038  1.1  christos 
   1039  1.1  christos       /* Simple relax.  */
   1040  1.1  christos       if (ip2k_test_page_insn (abfd, sec, irel, misc))
   1041  1.1  christos 	{
   1042  1.1  christos 	  if (!ip2k_delete_page_insn (abfd, sec, irel, again, misc))
   1043  1.1  christos 	    return FALSE;
   1044  1.1  christos 
   1045  1.1  christos 	  continue;
   1046  1.1  christos 	}
   1047  1.1  christos     }
   1048  1.1  christos 
   1049  1.1  christos   return TRUE;
   1050  1.1  christos }
   1051  1.1  christos 
   1052  1.1  christos /* This function handles relaxing for the ip2k.
   1053  1.1  christos 
   1054  1.1  christos    Principle: Start with the first page and remove page instructions that
   1055  1.1  christos    are not require on this first page. By removing page instructions more
   1056  1.1  christos    code will fit into this page - repeat until nothing more can be achieved
   1057  1.1  christos    for this page. Move on to the next page.
   1058  1.1  christos 
   1059  1.1  christos    Processing the pages one at a time from the lowest page allows a removal
   1060  1.1  christos    only policy to be used - pages can be removed but are never reinserted.  */
   1061  1.1  christos 
   1062  1.1  christos static bfd_boolean
   1063  1.1  christos ip2k_elf_relax_section (bfd *abfd,
   1064  1.1  christos 			asection *sec,
   1065  1.1  christos 			struct bfd_link_info *link_info,
   1066  1.1  christos 			bfd_boolean *again)
   1067  1.1  christos {
   1068  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1069  1.1  christos   Elf_Internal_Rela *internal_relocs;
   1070  1.1  christos   bfd_byte *contents = NULL;
   1071  1.1  christos   Elf_Internal_Sym *isymbuf = NULL;
   1072  1.1  christos   static asection * first_section = NULL;
   1073  1.1  christos   static unsigned long search_addr;
   1074  1.1  christos   static unsigned long page_start = 0;
   1075  1.1  christos   static unsigned long page_end = 0;
   1076  1.1  christos   static unsigned int pass = 0;
   1077  1.1  christos   static bfd_boolean new_pass = FALSE;
   1078  1.1  christos   static bfd_boolean changed = FALSE;
   1079  1.1  christos   struct misc misc;
   1080  1.1  christos 
   1081  1.1  christos   /* Assume nothing changes.  */
   1082  1.1  christos   *again = FALSE;
   1083  1.1  christos 
   1084  1.1  christos   if (first_section == NULL)
   1085  1.1  christos     {
   1086  1.1  christos       ip2k_relaxed = TRUE;
   1087  1.1  christos       first_section = sec;
   1088  1.1  christos     }
   1089  1.1  christos 
   1090  1.1  christos   if (first_section == sec)
   1091  1.1  christos     {
   1092  1.1  christos       pass++;
   1093  1.1  christos       new_pass = TRUE;
   1094  1.1  christos     }
   1095  1.1  christos 
   1096  1.1  christos   /* We don't have to do anything for a relocatable link,
   1097  1.1  christos      if this section does not have relocs, or if this is
   1098  1.1  christos      not a code section.  */
   1099  1.6  christos   if (bfd_link_relocatable (link_info)
   1100  1.1  christos       || (sec->flags & SEC_RELOC) == 0
   1101  1.1  christos       || sec->reloc_count == 0
   1102  1.1  christos       || (sec->flags & SEC_CODE) == 0)
   1103  1.1  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.1  christos          we havn't relaxed yet. Note that the pass count is reset
   1148  1.1  christos          each time a page is complete in order to move on to the next page.
   1149  1.1  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.1  christos 	  new_pass = FALSE;
   1154  1.1  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.1  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.1  christos 	  new_pass = FALSE;
   1175  1.1  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.1  christos           if (!ip2k_elf_relax_section_page (abfd, sec, &changed, &misc, page_start, page_end))
   1185  1.1  christos 	    return FALSE;
   1186  1.1  christos 	}
   1187  1.1  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.1  christos   if (internal_relocs != NULL
   1214  1.1  christos       && elf_section_data (sec)->relocs != internal_relocs)
   1215  1.1  christos     free (internal_relocs);
   1216  1.1  christos 
   1217  1.1  christos   return TRUE;
   1218  1.1  christos 
   1219  1.1  christos  error_return:
   1220  1.1  christos   if (isymbuf != NULL
   1221  1.1  christos       && symtab_hdr->contents != (unsigned char *) isymbuf)
   1222  1.1  christos     free (isymbuf);
   1223  1.1  christos   if (contents != NULL
   1224  1.1  christos       && elf_section_data (sec)->this_hdr.contents != contents)
   1225  1.1  christos     free (contents);
   1226  1.1  christos   if (internal_relocs != NULL
   1227  1.1  christos       && elf_section_data (sec)->relocs != internal_relocs)
   1228  1.1  christos     free (internal_relocs);
   1229  1.1  christos   return FALSE;
   1230  1.1  christos }
   1231  1.1  christos 
   1232  1.1  christos /* Set the howto pointer for a IP2K ELF reloc.  */
   1233  1.1  christos 
   1234  1.1  christos static void
   1235  1.1  christos ip2k_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
   1236  1.1  christos 			 arelent * cache_ptr,
   1237  1.1  christos 			 Elf_Internal_Rela * dst)
   1238  1.1  christos {
   1239  1.1  christos   unsigned int r_type;
   1240  1.1  christos 
   1241  1.1  christos   r_type = ELF32_R_TYPE (dst->r_info);
   1242  1.3  christos   if (r_type >= (unsigned int) R_IP2K_max)
   1243  1.3  christos     {
   1244  1.7  christos       /* xgettext:c-format */
   1245  1.5  christos       _bfd_error_handler (_("%B: invalid IP2K reloc number: %d"), abfd, r_type);
   1246  1.3  christos       r_type = 0;
   1247  1.3  christos     }
   1248  1.1  christos   cache_ptr->howto = & ip2k_elf_howto_table [r_type];
   1249  1.1  christos }
   1250  1.1  christos 
   1251  1.1  christos /* Perform a single relocation.
   1252  1.1  christos    By default we use the standard BFD routines.  */
   1253  1.1  christos 
   1254  1.1  christos static bfd_reloc_status_type
   1255  1.1  christos ip2k_final_link_relocate (reloc_howto_type *  howto,
   1256  1.1  christos 			  bfd *               input_bfd,
   1257  1.1  christos 			  asection *          input_section,
   1258  1.1  christos 			  bfd_byte *          contents,
   1259  1.1  christos 			  Elf_Internal_Rela * rel,
   1260  1.1  christos 			  bfd_vma             relocation)
   1261  1.1  christos {
   1262  1.1  christos   static bfd_vma page_addr = 0;
   1263  1.1  christos 
   1264  1.1  christos   bfd_reloc_status_type r = bfd_reloc_ok;
   1265  1.1  christos   switch (howto->type)
   1266  1.1  christos     {
   1267  1.1  christos       /* Handle data space relocations.  */
   1268  1.1  christos     case R_IP2K_FR9:
   1269  1.1  christos     case R_IP2K_BANK:
   1270  1.1  christos       if ((relocation & IP2K_DATA_MASK) == IP2K_DATA_VALUE)
   1271  1.1  christos 	relocation &= ~IP2K_DATA_MASK;
   1272  1.1  christos       else
   1273  1.1  christos 	r = bfd_reloc_notsupported;
   1274  1.1  christos       break;
   1275  1.1  christos 
   1276  1.1  christos     case R_IP2K_LO8DATA:
   1277  1.1  christos     case R_IP2K_HI8DATA:
   1278  1.1  christos     case R_IP2K_EX8DATA:
   1279  1.1  christos       break;
   1280  1.1  christos 
   1281  1.1  christos       /* Handle insn space relocations.  */
   1282  1.1  christos     case R_IP2K_PAGE3:
   1283  1.1  christos       page_addr = BASEADDR (input_section) + rel->r_offset;
   1284  1.1  christos       if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
   1285  1.1  christos 	relocation &= ~IP2K_INSN_MASK;
   1286  1.1  christos       else
   1287  1.1  christos 	r = bfd_reloc_notsupported;
   1288  1.1  christos       break;
   1289  1.1  christos 
   1290  1.1  christos     case R_IP2K_ADDR16CJP:
   1291  1.1  christos       if (BASEADDR (input_section) + rel->r_offset != page_addr + 2)
   1292  1.1  christos 	{
   1293  1.1  christos 	  /* No preceding page instruction, verify that it isn't needed.  */
   1294  1.1  christos 	  if (PAGENO (relocation + rel->r_addend) !=
   1295  1.1  christos 	      ip2k_nominal_page_bits (input_bfd, input_section,
   1296  1.1  christos 	      			      rel->r_offset, contents))
   1297  1.7  christos 	    /* xgettext:c-format */
   1298  1.1  christos 	    _bfd_error_handler (_("ip2k linker: missing page instruction at 0x%08lx (dest = 0x%08lx)."),
   1299  1.1  christos 				BASEADDR (input_section) + rel->r_offset,
   1300  1.1  christos 				relocation + rel->r_addend);
   1301  1.1  christos         }
   1302  1.1  christos       else if (ip2k_relaxed)
   1303  1.1  christos         {
   1304  1.1  christos           /* Preceding page instruction. Verify that the page instruction is
   1305  1.1  christos              really needed. One reason for the relaxation to miss a page is if
   1306  1.1  christos              the section is not marked as executable.  */
   1307  1.1  christos 	  if (!ip2k_is_switch_table_128 (input_bfd, input_section,
   1308  1.1  christos 					 rel->r_offset - 2, contents)
   1309  1.1  christos 	      && !ip2k_is_switch_table_256 (input_bfd, input_section,
   1310  1.1  christos 					    rel->r_offset - 2, contents)
   1311  1.1  christos 	      && (PAGENO (relocation + rel->r_addend) ==
   1312  1.1  christos 		  ip2k_nominal_page_bits (input_bfd, input_section,
   1313  1.1  christos 					  rel->r_offset - 2, contents)))
   1314  1.7  christos 	    /* xgettext:c-format */
   1315  1.1  christos 	    _bfd_error_handler (_("ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."),
   1316  1.1  christos 				page_addr,
   1317  1.1  christos 				relocation + rel->r_addend);
   1318  1.1  christos         }
   1319  1.1  christos       if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
   1320  1.1  christos 	relocation &= ~IP2K_INSN_MASK;
   1321  1.1  christos       else
   1322  1.1  christos 	r = bfd_reloc_notsupported;
   1323  1.1  christos       break;
   1324  1.1  christos 
   1325  1.1  christos     case R_IP2K_LO8INSN:
   1326  1.1  christos     case R_IP2K_HI8INSN:
   1327  1.1  christos     case R_IP2K_PC_SKIP:
   1328  1.1  christos       if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
   1329  1.1  christos 	relocation &= ~IP2K_INSN_MASK;
   1330  1.1  christos       else
   1331  1.1  christos 	r = bfd_reloc_notsupported;
   1332  1.1  christos       break;
   1333  1.1  christos 
   1334  1.1  christos     case R_IP2K_16:
   1335  1.1  christos       /* If this is a relocation involving a TEXT
   1336  1.1  christos 	 symbol, reduce it to a word address.  */
   1337  1.1  christos       if ((relocation & IP2K_INSN_MASK) == IP2K_INSN_VALUE)
   1338  1.1  christos 	howto = &ip2k_elf_howto_table[ (int) R_IP2K_TEXT];
   1339  1.1  christos       break;
   1340  1.1  christos 
   1341  1.1  christos       /* Pass others through.  */
   1342  1.1  christos     default:
   1343  1.1  christos       break;
   1344  1.1  christos     }
   1345  1.1  christos 
   1346  1.1  christos   /* Only install relocation if above tests did not disqualify it.  */
   1347  1.1  christos   if (r == bfd_reloc_ok)
   1348  1.1  christos     r = _bfd_final_link_relocate (howto, input_bfd, input_section,
   1349  1.1  christos 				  contents, rel->r_offset,
   1350  1.1  christos 				  relocation, rel->r_addend);
   1351  1.1  christos 
   1352  1.1  christos   return r;
   1353  1.1  christos }
   1354  1.1  christos 
   1355  1.1  christos /* Relocate a IP2K ELF section.
   1356  1.1  christos 
   1357  1.1  christos    The RELOCATE_SECTION function is called by the new ELF backend linker
   1358  1.1  christos    to handle the relocations for a section.
   1359  1.1  christos 
   1360  1.1  christos    The relocs are always passed as Rela structures; if the section
   1361  1.1  christos    actually uses Rel structures, the r_addend field will always be
   1362  1.1  christos    zero.
   1363  1.1  christos 
   1364  1.1  christos    This function is responsible for adjusting the section contents as
   1365  1.1  christos    necessary, and (if using Rela relocs and generating a relocatable
   1366  1.1  christos    output file) adjusting the reloc addend as necessary.
   1367  1.1  christos 
   1368  1.1  christos    This function does not have to worry about setting the reloc
   1369  1.1  christos    address or the reloc symbol index.
   1370  1.1  christos 
   1371  1.1  christos    LOCAL_SYMS is a pointer to the swapped in local symbols.
   1372  1.1  christos 
   1373  1.1  christos    LOCAL_SECTIONS is an array giving the section in the input file
   1374  1.1  christos    corresponding to the st_shndx field of each local symbol.
   1375  1.1  christos 
   1376  1.1  christos    The global hash table entry for the global symbols can be found
   1377  1.1  christos    via elf_sym_hashes (input_bfd).
   1378  1.1  christos 
   1379  1.1  christos    When generating relocatable output, this function must handle
   1380  1.1  christos    STB_LOCAL/STT_SECTION symbols specially.  The output symbol is
   1381  1.1  christos    going to be the section symbol corresponding to the output
   1382  1.1  christos    section, which means that the addend must be adjusted
   1383  1.1  christos    accordingly.  */
   1384  1.1  christos 
   1385  1.1  christos static bfd_boolean
   1386  1.1  christos ip2k_elf_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
   1387  1.1  christos 			   struct bfd_link_info *info,
   1388  1.1  christos 			   bfd *input_bfd,
   1389  1.1  christos 			   asection *input_section,
   1390  1.1  christos 			   bfd_byte *contents,
   1391  1.1  christos 			   Elf_Internal_Rela *relocs,
   1392  1.1  christos 			   Elf_Internal_Sym *local_syms,
   1393  1.1  christos 			   asection **local_sections)
   1394  1.1  christos {
   1395  1.1  christos   Elf_Internal_Shdr *symtab_hdr;
   1396  1.1  christos   struct elf_link_hash_entry **sym_hashes;
   1397  1.1  christos   Elf_Internal_Rela *rel;
   1398  1.1  christos   Elf_Internal_Rela *relend;
   1399  1.1  christos 
   1400  1.1  christos   symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
   1401  1.1  christos   sym_hashes = elf_sym_hashes (input_bfd);
   1402  1.1  christos   relend     = relocs + input_section->reloc_count;
   1403  1.1  christos 
   1404  1.1  christos   for (rel = relocs; rel < relend; rel ++)
   1405  1.1  christos     {
   1406  1.1  christos       reloc_howto_type *           howto;
   1407  1.1  christos       unsigned long                r_symndx;
   1408  1.1  christos       Elf_Internal_Sym *           sym;
   1409  1.1  christos       asection *                   sec;
   1410  1.1  christos       struct elf_link_hash_entry * h;
   1411  1.1  christos       bfd_vma                      relocation;
   1412  1.1  christos       bfd_reloc_status_type        r;
   1413  1.1  christos       const char *                 name = NULL;
   1414  1.1  christos       int                          r_type;
   1415  1.1  christos 
   1416  1.1  christos       r_type = ELF32_R_TYPE (rel->r_info);
   1417  1.1  christos       r_symndx = ELF32_R_SYM (rel->r_info);
   1418  1.1  christos       howto  = ip2k_elf_howto_table + r_type;
   1419  1.1  christos       h      = NULL;
   1420  1.1  christos       sym    = NULL;
   1421  1.1  christos       sec    = NULL;
   1422  1.1  christos 
   1423  1.1  christos       if (r_symndx < symtab_hdr->sh_info)
   1424  1.1  christos 	{
   1425  1.1  christos 	  sym = local_syms + r_symndx;
   1426  1.1  christos 	  sec = local_sections [r_symndx];
   1427  1.1  christos 	  relocation = BASEADDR (sec) + sym->st_value;
   1428  1.1  christos 
   1429  1.1  christos 	  name = bfd_elf_string_from_elf_section
   1430  1.1  christos 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
   1431  1.1  christos 	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
   1432  1.1  christos 	}
   1433  1.1  christos       else
   1434  1.1  christos 	{
   1435  1.1  christos 	  bfd_boolean warned, ignored;
   1436  1.1  christos 	  bfd_boolean unresolved_reloc;
   1437  1.1  christos 
   1438  1.1  christos 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
   1439  1.1  christos 				   r_symndx, symtab_hdr, sym_hashes,
   1440  1.1  christos 				   h, sec, relocation,
   1441  1.1  christos 				   unresolved_reloc, warned, ignored);
   1442  1.1  christos 
   1443  1.1  christos 	  name = h->root.root.string;
   1444  1.1  christos 	}
   1445  1.1  christos 
   1446  1.1  christos       if (sec != NULL && discarded_section (sec))
   1447  1.1  christos 	RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
   1448  1.1  christos 					 rel, 1, relend, howto, 0, contents);
   1449  1.1  christos 
   1450  1.6  christos       if (bfd_link_relocatable (info))
   1451  1.1  christos 	continue;
   1452  1.1  christos 
   1453  1.1  christos       /* Finally, the sole IP2K-specific part.  */
   1454  1.1  christos       r = ip2k_final_link_relocate (howto, input_bfd, input_section,
   1455  1.1  christos 				     contents, rel, relocation);
   1456  1.1  christos 
   1457  1.1  christos       if (r != bfd_reloc_ok)
   1458  1.1  christos 	{
   1459  1.1  christos 	  const char * msg = NULL;
   1460  1.1  christos 
   1461  1.1  christos 	  switch (r)
   1462  1.1  christos 	    {
   1463  1.1  christos 	    case bfd_reloc_overflow:
   1464  1.6  christos 	      (*info->callbacks->reloc_overflow)
   1465  1.1  christos 		(info, (h ? &h->root : NULL), name, howto->name,
   1466  1.1  christos 		 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
   1467  1.1  christos 	      break;
   1468  1.1  christos 
   1469  1.1  christos 	    case bfd_reloc_undefined:
   1470  1.6  christos 	      (*info->callbacks->undefined_symbol)
   1471  1.1  christos 		(info, name, input_bfd, input_section, rel->r_offset, TRUE);
   1472  1.1  christos 	      break;
   1473  1.1  christos 
   1474  1.1  christos 	    case bfd_reloc_outofrange:
   1475  1.1  christos 	      msg = _("internal error: out of range error");
   1476  1.1  christos 	      break;
   1477  1.1  christos 
   1478  1.1  christos 	      /* This is how ip2k_final_link_relocate tells us of a non-kosher
   1479  1.1  christos                  reference between insn & data address spaces.  */
   1480  1.1  christos 	    case bfd_reloc_notsupported:
   1481  1.1  christos               if (sym != NULL) /* Only if it's not an unresolved symbol.  */
   1482  1.1  christos 	         msg = _("unsupported relocation between data/insn address spaces");
   1483  1.1  christos 	      break;
   1484  1.1  christos 
   1485  1.1  christos 	    case bfd_reloc_dangerous:
   1486  1.1  christos 	      msg = _("internal error: dangerous relocation");
   1487  1.1  christos 	      break;
   1488  1.1  christos 
   1489  1.1  christos 	    default:
   1490  1.1  christos 	      msg = _("internal error: unknown error");
   1491  1.1  christos 	      break;
   1492  1.1  christos 	    }
   1493  1.1  christos 
   1494  1.1  christos 	  if (msg)
   1495  1.6  christos 	    (*info->callbacks->warning) (info, msg, name, input_bfd,
   1496  1.6  christos 					 input_section, rel->r_offset);
   1497  1.1  christos 	}
   1498  1.1  christos     }
   1499  1.1  christos 
   1500  1.1  christos   return TRUE;
   1501  1.1  christos }
   1502  1.1  christos 
   1503  1.3  christos #define TARGET_BIG_SYM	 ip2k_elf32_vec
   1504  1.1  christos #define TARGET_BIG_NAME  "elf32-ip2k"
   1505  1.1  christos 
   1506  1.1  christos #define ELF_ARCH	 bfd_arch_ip2k
   1507  1.1  christos #define ELF_MACHINE_CODE EM_IP2K
   1508  1.1  christos #define ELF_MACHINE_ALT1 EM_IP2K_OLD
   1509  1.1  christos #define ELF_MAXPAGESIZE  1 /* No pages on the IP2K.  */
   1510  1.1  christos 
   1511  1.1  christos #define elf_info_to_howto_rel			NULL
   1512  1.1  christos #define elf_info_to_howto			ip2k_info_to_howto_rela
   1513  1.1  christos 
   1514  1.1  christos #define elf_backend_can_gc_sections     	1
   1515  1.1  christos #define elf_backend_rela_normal			1
   1516  1.1  christos #define elf_backend_relocate_section		ip2k_elf_relocate_section
   1517  1.1  christos 
   1518  1.1  christos #define elf_symbol_leading_char			'_'
   1519  1.1  christos #define bfd_elf32_bfd_reloc_type_lookup		ip2k_reloc_type_lookup
   1520  1.1  christos #define bfd_elf32_bfd_reloc_name_lookup	ip2k_reloc_name_lookup
   1521  1.1  christos #define bfd_elf32_bfd_relax_section		ip2k_elf_relax_section
   1522  1.1  christos 
   1523  1.1  christos #include "elf32-target.h"
   1524